animation_editor_plugin.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  1. /*************************************************************************/
  2. /* animation_editor_plugin.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 "animation_editor_plugin.h"
  30. #include "io/resource_loader.h"
  31. class AnimationEditor_TrackEditor : public Object {
  32. OBJ_TYPE(AnimationEditor_TrackEditor,Object);
  33. protected:
  34. bool _set(const StringName& p_name, const Variant& p_value) {
  35. if (anim.is_null())
  36. return false;
  37. String name=p_name;
  38. if (name=="track/interpolation") {
  39. anim_editor->_internal_set_interpolation_type(track,Animation::InterpolationType(p_value.operator int()));
  40. } else if (name.begins_with("keys/")) {
  41. int key = name.get_slice("/",1).to_int();
  42. ERR_FAIL_INDEX_V( key,anim->track_get_key_count(track), false );
  43. String what = name.get_slice("/",2);
  44. float time = anim->track_get_key_time(track,key);
  45. float transition = anim->track_get_key_transition(track,key);
  46. if (what=="time") {
  47. Variant v = anim->track_get_key_value(track,key);
  48. anim_editor->_internal_set_key(track,time,transition,v);
  49. return true;
  50. }
  51. if (what=="transition") {
  52. transition=p_value;
  53. Variant v = anim->track_get_key_value(track,key);
  54. anim_editor->_internal_set_key(track,time,transition,v);
  55. return true;
  56. }
  57. switch(anim->track_get_type(track)) {
  58. case Animation::TYPE_TRANSFORM: {
  59. Vector3 scale,loc;
  60. Quat rot;
  61. anim->transform_track_get_key(track,key,&loc,&rot,&scale);
  62. if (what=="loc") {
  63. loc=p_value;
  64. } else if (what=="scale") {
  65. scale=p_value;
  66. } else if (what=="rot") {
  67. rot=p_value;
  68. } else {
  69. return false; //meh
  70. }
  71. Dictionary k;
  72. k["rot"]=rot;
  73. k["loc"]=loc;
  74. k["scale"]=scale;
  75. anim_editor->_internal_set_key(track,time,transition,k);
  76. } break;
  77. case Animation::TYPE_METHOD: {
  78. } break;
  79. case Animation::TYPE_VALUE: {
  80. if (what=="value")
  81. anim_editor->_internal_set_key(track,time,transition,p_value);
  82. } break;
  83. default: { return false; }
  84. }
  85. } else
  86. return false;
  87. return true;
  88. }
  89. bool _get(const StringName& p_name,Variant &r_ret) const {
  90. if (anim.is_null())
  91. return false;
  92. String name=p_name;
  93. if (name=="track/interpolation") {
  94. r_ret=anim->track_get_interpolation_type(track);
  95. } else if (name.begins_with("keys/")) {
  96. int key = name.get_slice("/",1).to_int();
  97. ERR_FAIL_INDEX_V( key,anim->track_get_key_count(track), Variant() );
  98. String what = name.get_slice("/",2);
  99. if (what=="time") {
  100. r_ret=anim->track_get_key_time(track,key);
  101. return true;
  102. }
  103. if (what=="transition") {
  104. r_ret=anim->track_get_key_transition(track,key);
  105. return true;
  106. }
  107. switch(anim->track_get_type(track)) {
  108. case Animation::TYPE_TRANSFORM: {
  109. Vector3 scale,loc;
  110. Quat rot;
  111. anim->transform_track_get_key(track,key,&loc,&rot,&scale);
  112. if (what=="loc") {
  113. r_ret= loc;
  114. } else if (what=="scale") {
  115. r_ret= scale;
  116. } else if (what=="rot") {
  117. r_ret= rot;
  118. }
  119. } break;
  120. case Animation::TYPE_METHOD: {
  121. } break;
  122. case Animation::TYPE_VALUE: {
  123. if (what=="value")
  124. r_ret= anim->track_get_key_value(track,key);
  125. } break;
  126. default: { return false; }
  127. }
  128. } else
  129. return false;
  130. return true;
  131. }
  132. void _get_property_list( List<PropertyInfo> *p_list) const {
  133. p_list->push_back(PropertyInfo(Variant::INT,"track/interpolation",PROPERTY_HINT_ENUM,"Nearest,Linear,Cubic") );
  134. if (anim.is_null())
  135. return;
  136. int keycount = anim->track_get_key_count(track);
  137. for(int i=0;i<keycount;i++) {
  138. p_list->push_back(PropertyInfo(Variant::REAL,"keys/"+itos(i)+"/time",PROPERTY_HINT_RANGE,"0,3600,0.001") );
  139. p_list->push_back(PropertyInfo(Variant::REAL,"keys/"+itos(i)+"/transition",PROPERTY_HINT_EXP_EASING) );
  140. switch(anim->track_get_type(track)) {
  141. case Animation::TYPE_TRANSFORM: {
  142. p_list->push_back(PropertyInfo(Variant::VECTOR3,"keys/"+itos(i)+"/loc" ) );
  143. p_list->push_back(PropertyInfo(Variant::QUAT,"keys/"+itos(i)+"/rot" ) );
  144. p_list->push_back(PropertyInfo(Variant::VECTOR3,"keys/"+itos(i)+"/scale" ) );
  145. } break;
  146. case Animation::TYPE_METHOD: {
  147. } break;
  148. case Animation::TYPE_VALUE: {
  149. Variant v = anim->track_get_key_value(track,i);
  150. PropertyHint hint=PROPERTY_HINT_NONE;
  151. String hint_string;
  152. if (v.get_type()==Variant::INT) {
  153. hint=PROPERTY_HINT_RANGE;
  154. hint_string="-16384,16384,1";
  155. } else if (v.get_type()==Variant::REAL) {
  156. hint=PROPERTY_HINT_RANGE;
  157. hint_string="-16384,16384,0.001";
  158. } else if (v.get_type()==Variant::OBJECT) {
  159. hint=PROPERTY_HINT_RESOURCE_TYPE;
  160. hint_string="Resource";
  161. }
  162. p_list->push_back(PropertyInfo(v.get_type(),"keys/"+itos(i)+"/value",hint,hint_string ) );
  163. } break;
  164. }
  165. }
  166. }
  167. public:
  168. AnimationEditor *anim_editor;
  169. Ref<Animation> anim;
  170. int track;
  171. AnimationEditor_TrackEditor() { }
  172. };
  173. void AnimationEditor::update_anim() {
  174. tracks->clear();
  175. key_editor->edit(NULL);
  176. TreeItem *root = tracks->create_item(NULL);
  177. TreeItem *sel=NULL;
  178. int selected_track=-1;
  179. if (animation->has_meta("_anim_editor_selected_track_"))
  180. selected_track=animation->get_meta("_anim_editor_selected_track_");
  181. for(int i=0;i<animation->get_track_count();i++) {
  182. String path = animation->track_get_path(i);
  183. TreeItem *track = tracks->create_item(root);
  184. track->set_text(0,itos(i));
  185. track->set_editable(0,false);
  186. track->set_text(1,path);
  187. track->set_editable(1,true);
  188. track->set_metadata(0,i);
  189. if (selected_track==i)
  190. sel=track;
  191. switch(animation->track_get_type(i)) {
  192. case Animation::TYPE_TRANSFORM: {
  193. track->set_icon(0,get_icon("Matrix","EditorIcons"));
  194. } break;
  195. case Animation::TYPE_METHOD: {
  196. track->set_icon(0,get_icon("TrackMethod","EditorIcons"));
  197. } break;
  198. case Animation::TYPE_VALUE: {
  199. track->set_icon(0,get_icon("TrackValue","EditorIcons"));
  200. } break;
  201. }
  202. }
  203. if (sel) {
  204. sel->select(1);
  205. _update_track_keys();
  206. } else {
  207. selected_track=-1;
  208. }
  209. }
  210. void AnimationEditor::_update_track_keys() {
  211. if (selected_track<0 || selected_track>=animation->get_track_count())
  212. return;
  213. track_editor->anim=animation;
  214. track_editor->track=selected_track;
  215. key_editor->edit(NULL);
  216. key_editor->edit(track_editor);
  217. if (animation->track_get_type(selected_track)==Animation::TYPE_VALUE) {
  218. key_time->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,160);
  219. key_type->show();
  220. } else {
  221. key_time->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,60);
  222. key_type->hide();
  223. }
  224. }
  225. void AnimationEditor::_track_path_changed() {
  226. TreeItem *ti=tracks->get_edited();
  227. int track=ti->get_metadata(0);
  228. String path=ti->get_text(1);
  229. if (track<0 || track>=animation->get_track_count())
  230. return;
  231. undo_redo->create_action("Create Anim Track");
  232. undo_redo->add_do_method(animation.ptr(),"track_set_path",track,path);
  233. undo_redo->add_undo_method(animation.ptr(),"track_set_path",track,animation->track_get_path(track));
  234. undo_redo->add_do_method(this,"_internal_check_update",animation);
  235. undo_redo->add_undo_method(this,"_internal_check_update",animation);
  236. undo_redo->commit_action();
  237. }
  238. void AnimationEditor::_track_selected() {
  239. TreeItem *ti=tracks->get_selected();
  240. if(!ti)
  241. return;
  242. selected_track=ti->get_metadata(0);
  243. animation->set_meta("_anim_editor_selected_track_",selected_track);
  244. _update_track_keys();
  245. }
  246. void AnimationEditor::_track_added() {
  247. undo_redo->create_action("Create Anim Track");
  248. undo_redo->add_do_method(animation.ptr(),"add_track",track_type->get_selected(),-1);
  249. undo_redo->add_undo_method(animation.ptr(),"remove_track",animation->get_track_count());
  250. undo_redo->add_do_method(this,"_internal_set_selected_track",animation->get_track_count(),animation);
  251. undo_redo->add_undo_method(this,"_internal_set_selected_track",selected_track,animation);
  252. undo_redo->add_do_method(this,"_internal_check_update",animation);
  253. undo_redo->add_undo_method(this,"_internal_check_update",animation);
  254. undo_redo->commit_action();
  255. update_anim();
  256. }
  257. void AnimationEditor::_track_removed() {
  258. if (selected_track<0 || selected_track>=animation->get_track_count())
  259. return;
  260. undo_redo->create_action("Remove Anim Track");
  261. undo_redo->add_do_method(animation.ptr(),"remove_track",selected_track);
  262. undo_redo->add_undo_method(animation.ptr(),"add_track",animation->track_get_type(selected_track),selected_track);
  263. undo_redo->add_undo_method(animation.ptr(),"track_set_path",selected_track,animation->track_get_path(selected_track));
  264. //todo interpolation
  265. for(int i=0;i<animation->track_get_key_count(selected_track);i++) {
  266. Variant v = animation->track_get_key_value(selected_track,i);
  267. float time = animation->track_get_key_time(selected_track,i);
  268. undo_redo->add_undo_method(animation.ptr(),"track_insert_key",selected_track,time,v);
  269. }
  270. int old_track=selected_track;
  271. if (selected_track>0)
  272. selected_track--;
  273. if (selected_track<0 || selected_track>=(animation->get_track_count()-1))
  274. selected_track=-1;
  275. undo_redo->add_do_method(this,"_internal_set_selected_track",selected_track,animation);
  276. undo_redo->add_undo_method(this,"_internal_set_selected_track",old_track,animation);
  277. undo_redo->add_do_method(this,"_internal_check_update",animation);
  278. undo_redo->add_undo_method(this,"_internal_check_update",animation);
  279. undo_redo->commit_action();
  280. }
  281. void AnimationEditor::_internal_set_interpolation_type(int p_track,Animation::InterpolationType p_type) {
  282. undo_redo->create_action("Set Interpolation");
  283. undo_redo->add_do_method(animation.ptr(),"track_set_interpolation_type",p_track,p_type);
  284. undo_redo->add_undo_method(animation.ptr(),"track_set_interpolation_type",p_track,animation->track_get_interpolation_type(p_track));
  285. undo_redo->add_do_method(this,"_internal_set_selected_track",selected_track,animation);
  286. undo_redo->add_undo_method(this,"_internal_set_selected_track",selected_track,animation);
  287. undo_redo->add_do_method(this,"_internal_check_update",animation);
  288. undo_redo->add_undo_method(this,"_internal_check_update",animation);
  289. undo_redo->commit_action();
  290. }
  291. void AnimationEditor::_internal_set_selected_track(int p_which,const Ref<Animation>& p_anim) {
  292. if (is_visible() && animation==p_anim) {
  293. selected_track=p_which;
  294. animation->set_meta("_anim_editor_selected_track_",selected_track);
  295. }
  296. }
  297. void AnimationEditor::_track_moved_up() {
  298. if (selected_track<0 || selected_track>=animation->get_track_count())
  299. return;
  300. if (selected_track<(animation->get_track_count()-1)) {
  301. undo_redo->create_action("Move Up Track");
  302. undo_redo->add_do_method(animation.ptr(),"track_move_up",selected_track);
  303. undo_redo->add_undo_method(animation.ptr(),"track_move_down",selected_track+1);
  304. undo_redo->add_do_method(this,"_internal_set_selected_track",selected_track+1,animation);
  305. undo_redo->add_undo_method(this,"_internal_set_selected_track",selected_track,animation);
  306. undo_redo->add_do_method(this,"_internal_check_update",animation);
  307. undo_redo->add_undo_method(this,"_internal_check_update",animation);
  308. undo_redo->commit_action();
  309. }
  310. }
  311. void AnimationEditor::_track_moved_down() {
  312. if (selected_track<0 || selected_track>=animation->get_track_count())
  313. return;
  314. if (selected_track>0) {
  315. undo_redo->create_action("Move Down Track");
  316. undo_redo->add_do_method(animation.ptr(),"track_move_down",selected_track);
  317. undo_redo->add_undo_method(animation.ptr(),"track_move_up",selected_track-1);
  318. undo_redo->add_do_method(this,"_internal_set_selected_track",selected_track-1,animation);
  319. undo_redo->add_undo_method(this,"_internal_set_selected_track",selected_track,animation);
  320. undo_redo->add_do_method(this,"_internal_check_update",animation);
  321. undo_redo->add_undo_method(this,"_internal_check_update",animation);
  322. undo_redo->commit_action();
  323. }
  324. }
  325. void AnimationEditor::_key_added() {
  326. if (selected_track<0 || selected_track>=animation->get_track_count())
  327. return;
  328. bool need_variant= animation->track_get_type(selected_track)==Animation::TYPE_VALUE;
  329. Variant v;
  330. if (need_variant) {
  331. switch(key_type->get_selected()) {
  332. case Variant::NIL: v=Variant(); break;
  333. case Variant::BOOL: v=false; break;
  334. case Variant::INT: v=0; break;
  335. case Variant::REAL: v=0.0; break;
  336. case Variant::STRING: v=""; break;
  337. case Variant::VECTOR2: v=Vector2(); break; // 5
  338. case Variant::RECT2: v=Rect2(); break;
  339. case Variant::VECTOR3: v=Vector3(); break;
  340. case Variant::PLANE: v=Plane(); break;
  341. case Variant::QUAT: v=Quat(); break;
  342. case Variant::_AABB: v=AABB(); break; //sorry naming convention fail :( not like it's used often // 10
  343. case Variant::MATRIX3: v=Matrix3(); break;
  344. case Variant::TRANSFORM: v=Transform(); break;
  345. case Variant::COLOR: v=Color(); break;
  346. case Variant::IMAGE: v=Image(); break;
  347. case Variant::NODE_PATH: v=NodePath(); break; // 15
  348. case Variant::_RID: v=RID(); break;
  349. case Variant::OBJECT: v=Variant(); break;
  350. case Variant::INPUT_EVENT: v=InputEvent(); break;
  351. case Variant::DICTIONARY: v=Dictionary(); break; // 20
  352. case Variant::ARRAY: v=Array(); break;
  353. case Variant::RAW_ARRAY: v=DVector<uint8_t>(); break;
  354. case Variant::INT_ARRAY: v=DVector<int>(); break;
  355. case Variant::REAL_ARRAY: v=DVector<real_t>(); break;
  356. case Variant::STRING_ARRAY: v=DVector<String>(); break; //25
  357. case Variant::VECTOR3_ARRAY: v=DVector<Vector3>(); break;
  358. case Variant::COLOR_ARRAY: v=DVector<Color>(); break;
  359. default: v=Variant(); break;
  360. }
  361. }
  362. float time = key_time->get_text().to_double();
  363. switch(animation->track_get_type(selected_track)) {
  364. case Animation::TYPE_TRANSFORM: {
  365. Dictionary d;
  366. d["loc"]=Vector3();
  367. d["rot"]=Quat();
  368. d["scale"]=Vector3(1,1,1);
  369. v=d;
  370. } break;
  371. case Animation::TYPE_VALUE: {
  372. //v=v
  373. } break;
  374. case Animation::TYPE_METHOD: {
  375. return; //not do anything yet
  376. } break;
  377. }
  378. _internal_set_key(selected_track,time,1.0,v);
  379. _update_track_keys();
  380. }
  381. void AnimationEditor::_internal_check_update(Ref<Animation> p_anim) {
  382. if (is_visible() && p_anim==animation) {
  383. update_anim();
  384. }
  385. }
  386. void AnimationEditor::_internal_set_key(int p_track, float p_time, float p_transition,const Variant& p_value) {
  387. int prev = animation->track_find_key(p_track,p_time);
  388. bool existing = (prev>=0) && (animation->track_get_key_time(p_track,prev)==p_time);
  389. undo_redo->create_action("Insert Key");
  390. undo_redo->add_do_method(animation.ptr(),"track_insert_key",p_track,p_time,p_value,p_transition);
  391. if (existing)
  392. undo_redo->add_undo_method(animation.ptr(),"track_insert_key",p_track,p_time,animation->track_get_key_value(p_track,existing),animation->track_get_key_transition(p_track,existing));
  393. else
  394. undo_redo->add_undo_method(animation.ptr(),"track_remove_key",p_track,prev+1);
  395. undo_redo->add_do_method(this,"_internal_check_update",animation);
  396. undo_redo->add_undo_method(this,"_internal_check_update",animation);
  397. undo_redo->commit_action();
  398. }
  399. void AnimationEditor::_key_removed() {
  400. if (selected_track<0 || selected_track>=animation->get_track_count())
  401. return;
  402. String sel=key_editor->get_selected_path();
  403. if (sel.get_slice_count("/")<2)
  404. return;
  405. if (sel.get_slice("/",0)!="keys")
  406. return;
  407. int key = sel.get_slice("/",1).to_int();
  408. if (key<0 || key>=animation->track_get_key_count(selected_track))
  409. return;
  410. undo_redo->create_action("Remove Key");
  411. Variant data = animation->track_get_key_value(selected_track,key);
  412. float time = animation->track_get_key_time(selected_track,key);
  413. undo_redo->add_do_method(animation.ptr(),"track_remove_key",selected_track,key);
  414. undo_redo->add_undo_method(animation.ptr(),"track_insert_key",selected_track,time,data);
  415. undo_redo->add_do_method(this,"_internal_check_update",animation);
  416. undo_redo->add_undo_method(this,"_internal_check_update",animation);
  417. undo_redo->commit_action();
  418. _update_track_keys();
  419. }
  420. void AnimationEditor::edit(const Ref<Animation>& p_animation) {
  421. animation=p_animation;
  422. if (!animation.is_null())
  423. update_anim();
  424. }
  425. void AnimationEditor::_bind_methods() {
  426. ObjectTypeDB::bind_method(_MD("_track_selected"),&AnimationEditor::_track_selected);
  427. ObjectTypeDB::bind_method(_MD("_track_added"),&AnimationEditor::_track_added);
  428. ObjectTypeDB::bind_method(_MD("_track_removed"),&AnimationEditor::_track_removed);
  429. ObjectTypeDB::bind_method(_MD("_track_moved_up"),&AnimationEditor::_track_moved_up);
  430. ObjectTypeDB::bind_method(_MD("_track_moved_down"),&AnimationEditor::_track_moved_down);
  431. ObjectTypeDB::bind_method(_MD("_track_path_changed"),&AnimationEditor::_track_path_changed);
  432. ObjectTypeDB::bind_method(_MD("_key_added"),&AnimationEditor::_key_added);
  433. ObjectTypeDB::bind_method(_MD("_key_removed"),&AnimationEditor::_key_removed);
  434. ObjectTypeDB::bind_method(_MD("_internal_check_update"),&AnimationEditor::_internal_check_update);
  435. ObjectTypeDB::bind_method(_MD("_internal_set_selected_track"),&AnimationEditor::_internal_set_selected_track);
  436. }
  437. void AnimationEditor::_notification(int p_what) {
  438. switch(p_what) {
  439. case NOTIFICATION_ENTER_SCENE: {
  440. add_track->set_icon( get_icon("Add","EditorIcons") );
  441. remove_track->set_icon( get_icon("Del","EditorIcons") );
  442. move_up_track->set_icon( get_icon("Up","EditorIcons") );
  443. move_down_track->set_icon( get_icon("Down","EditorIcons") );
  444. time_icon->set_texture( get_icon("Time","EditorIcons") );
  445. add_key->set_icon( get_icon("Add","EditorIcons") );
  446. remove_key->set_icon( get_icon("Del","EditorIcons") );
  447. } break;
  448. }
  449. }
  450. AnimationEditor::AnimationEditor() {
  451. panel = memnew( Panel );
  452. add_child(panel);
  453. panel->set_area_as_parent_rect();
  454. Control *left_pane = memnew( Control );
  455. panel->add_child(left_pane);
  456. left_pane->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5);
  457. left_pane->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,0);
  458. Label *l = memnew( Label );
  459. l->set_text("Track List:");
  460. l->set_pos(Point2(5,5));
  461. left_pane->add_child(l);
  462. /*
  463. track_name = memnew( LineEdit );
  464. track_name->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,10);
  465. track_name->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,25);
  466. track_name->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,80);
  467. track_name->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_BEGIN,45);
  468. left_pane->add_child(track_name);
  469. */
  470. track_type = memnew( OptionButton );
  471. track_type->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,10);
  472. track_type->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,25);
  473. track_type->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,115);
  474. track_type->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_BEGIN,45);
  475. left_pane->add_child(track_type);
  476. track_type->add_item("Transform",Animation::TYPE_TRANSFORM);
  477. track_type->add_item("Value",Animation::TYPE_VALUE);
  478. track_type->add_item("Method",Animation::TYPE_METHOD);
  479. add_track = memnew( Button );
  480. add_track->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,110);
  481. add_track->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,25);
  482. add_track->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,90);
  483. add_track->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_BEGIN,45);
  484. left_pane->add_child(add_track);
  485. remove_track = memnew( Button );
  486. remove_track->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,85);
  487. remove_track->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,25);
  488. remove_track->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,60);
  489. remove_track->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_BEGIN,45);
  490. left_pane->add_child(remove_track);
  491. move_up_track = memnew( Button );
  492. move_up_track->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,55);
  493. move_up_track->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,25);
  494. move_up_track->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,30);
  495. move_up_track->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_BEGIN,45);
  496. left_pane->add_child(move_up_track);
  497. move_down_track = memnew( Button );
  498. move_down_track->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,25);
  499. move_down_track->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,25);
  500. move_down_track->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,0);
  501. move_down_track->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_BEGIN,45);
  502. left_pane->add_child(move_down_track);
  503. tracks = memnew(Tree);
  504. tracks->set_columns(2);
  505. tracks->set_column_expand(0,false);
  506. tracks->set_column_min_width(0,55);
  507. tracks->set_column_expand(1,true);
  508. tracks->set_column_min_width(1,100);
  509. tracks->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,55);
  510. tracks->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,0);
  511. tracks->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,10);
  512. tracks->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,5);
  513. tracks->set_hide_root(true);
  514. left_pane->add_child(tracks);
  515. Control *right_pane = memnew( Control );
  516. panel->add_child(right_pane);
  517. right_pane->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5);
  518. right_pane->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,5);
  519. right_pane->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,0);
  520. l = memnew( Label );
  521. l->set_text("Track Keys:");
  522. l->set_pos(Point2(5,5));
  523. right_pane->add_child(l);
  524. time_icon = memnew( TextureFrame );
  525. time_icon->set_pos(Point2(8,28));
  526. right_pane->add_child(time_icon);
  527. key_time = memnew( LineEdit );
  528. key_time->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,24);
  529. key_time->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,160);
  530. key_time->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,25);
  531. key_time->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_BEGIN,45);
  532. key_time->set_text("0.0");
  533. right_pane->add_child(key_time);
  534. key_type = memnew( OptionButton );
  535. key_type->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,160);
  536. key_type->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,60);
  537. key_type->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,25);
  538. key_type->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_BEGIN,45);
  539. right_pane->add_child(key_type);
  540. for(int i=0;i<Variant::VARIANT_MAX;i++) {
  541. key_type->add_item(Variant::get_type_name(Variant::Type(i)));
  542. }
  543. add_key = memnew( Button );
  544. add_key->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,55);
  545. add_key->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,30);
  546. add_key->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,25);
  547. add_key->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_BEGIN,45);
  548. right_pane->add_child(add_key);
  549. remove_key = memnew( Button );
  550. remove_key->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,25);
  551. remove_key->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,0);
  552. remove_key->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,25);
  553. remove_key->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_BEGIN,45);
  554. right_pane->add_child(remove_key);
  555. key_editor = memnew(PropertyEditor);
  556. key_editor->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,55);
  557. key_editor->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,0);
  558. key_editor->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,10);
  559. key_editor->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,5);
  560. key_editor->hide_top_label();
  561. right_pane->add_child(key_editor);
  562. track_editor = memnew( AnimationEditor_TrackEditor );
  563. track_editor->anim_editor=this;
  564. selected_track=-1;
  565. add_track->connect("pressed", this,"_track_added");
  566. remove_track->connect("pressed", this,"_track_removed");
  567. move_up_track->connect("pressed", this,"_track_moved_up");
  568. move_down_track->connect("pressed", this,"_track_moved_down");
  569. tracks->connect("cell_selected", this,"_track_selected");
  570. tracks->connect("item_edited", this,"_track_path_changed");
  571. add_key->connect("pressed", this,"_key_added");
  572. remove_key->connect("pressed", this,"_key_removed");
  573. }
  574. AnimationEditor::~AnimationEditor() {
  575. memdelete(track_editor);
  576. }
  577. void AnimationEditorPlugin::edit(Object *p_node) {
  578. animation_editor->set_undo_redo(&get_undo_redo());
  579. if (p_node && p_node->cast_to<Animation>()) {
  580. animation_editor->edit( p_node->cast_to<Animation>() );
  581. animation_editor->show();
  582. } else
  583. animation_editor->hide();
  584. }
  585. bool AnimationEditorPlugin::handles(Object *p_node) const{
  586. return p_node->is_type("Animation");
  587. }
  588. void AnimationEditorPlugin::make_visible(bool p_visible){
  589. if (p_visible)
  590. animation_editor->show();
  591. else
  592. animation_editor->hide();
  593. }
  594. AnimationEditorPlugin::AnimationEditorPlugin(EditorNode *p_node) {
  595. animation_editor = memnew( AnimationEditor );
  596. p_node->get_viewport()->add_child(animation_editor);
  597. animation_editor->set_area_as_parent_rect();
  598. animation_editor->hide();
  599. }