sprite_frames_editor_plugin.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848
  1. /*************************************************************************/
  2. /* sprite_frames_editor_plugin.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 "sprite_frames_editor_plugin.h"
  31. #include "editor/editor_settings.h"
  32. #include "io/resource_loader.h"
  33. #include "project_settings.h"
  34. #include "scene/3d/sprite_3d.h"
  35. void SpriteFramesEditor::_gui_input(Ref<InputEvent> p_event) {
  36. }
  37. void SpriteFramesEditor::_notification(int p_what) {
  38. if (p_what == NOTIFICATION_PHYSICS_PROCESS) {
  39. }
  40. if (p_what == NOTIFICATION_ENTER_TREE) {
  41. load->set_icon(get_icon("Load", "EditorIcons"));
  42. _delete->set_icon(get_icon("Remove", "EditorIcons"));
  43. new_anim->set_icon(get_icon("New", "EditorIcons"));
  44. remove_anim->set_icon(get_icon("Remove", "EditorIcons"));
  45. }
  46. if (p_what == NOTIFICATION_READY) {
  47. //NodePath("/root")->connect("node_removed", this,"_node_removed",Vector<Variant>(),true);
  48. }
  49. if (p_what == NOTIFICATION_DRAW) {
  50. }
  51. }
  52. void SpriteFramesEditor::_file_load_request(const PoolVector<String> &p_path, int p_at_pos) {
  53. ERR_FAIL_COND(!frames->has_animation(edited_anim));
  54. List<Ref<Texture> > resources;
  55. for (int i = 0; i < p_path.size(); i++) {
  56. Ref<Texture> resource;
  57. resource = ResourceLoader::load(p_path[i]);
  58. if (resource.is_null()) {
  59. dialog->set_text(TTR("ERROR: Couldn't load frame resource!"));
  60. dialog->set_title(TTR("Error!"));
  61. //dialog->get_cancel()->set_text("Close");
  62. dialog->get_ok()->set_text(TTR("Close"));
  63. dialog->popup_centered_minsize();
  64. return; ///beh should show an error i guess
  65. }
  66. resources.push_back(resource);
  67. }
  68. if (resources.empty()) {
  69. //print_line("added frames!");
  70. return;
  71. }
  72. undo_redo->create_action(TTR("Add Frame"));
  73. int fc = frames->get_frame_count(edited_anim);
  74. int count = 0;
  75. for (List<Ref<Texture> >::Element *E = resources.front(); E; E = E->next()) {
  76. undo_redo->add_do_method(frames, "add_frame", edited_anim, E->get(), p_at_pos == -1 ? -1 : p_at_pos + count);
  77. undo_redo->add_undo_method(frames, "remove_frame", edited_anim, p_at_pos == -1 ? fc : p_at_pos);
  78. count++;
  79. }
  80. undo_redo->add_do_method(this, "_update_library");
  81. undo_redo->add_undo_method(this, "_update_library");
  82. undo_redo->commit_action();
  83. //print_line("added frames!");
  84. }
  85. void SpriteFramesEditor::_load_pressed() {
  86. ERR_FAIL_COND(!frames->has_animation(edited_anim));
  87. loading_scene = false;
  88. file->clear_filters();
  89. List<String> extensions;
  90. ResourceLoader::get_recognized_extensions_for_type("Texture", &extensions);
  91. for (int i = 0; i < extensions.size(); i++)
  92. file->add_filter("*." + extensions[i]);
  93. file->set_mode(EditorFileDialog::MODE_OPEN_FILES);
  94. file->popup_centered_ratio();
  95. }
  96. void SpriteFramesEditor::_paste_pressed() {
  97. ERR_FAIL_COND(!frames->has_animation(edited_anim));
  98. Ref<Texture> r = EditorSettings::get_singleton()->get_resource_clipboard();
  99. if (!r.is_valid()) {
  100. dialog->set_text(TTR("Resource clipboard is empty or not a texture!"));
  101. dialog->set_title(TTR("Error!"));
  102. //dialog->get_cancel()->set_text("Close");
  103. dialog->get_ok()->set_text(TTR("Close"));
  104. dialog->popup_centered_minsize();
  105. return; ///beh should show an error i guess
  106. }
  107. undo_redo->create_action(TTR("Paste Frame"));
  108. undo_redo->add_do_method(frames, "add_frame", edited_anim, r);
  109. undo_redo->add_undo_method(frames, "remove_frame", edited_anim, frames->get_frame_count(edited_anim));
  110. undo_redo->add_do_method(this, "_update_library");
  111. undo_redo->add_undo_method(this, "_update_library");
  112. undo_redo->commit_action();
  113. }
  114. void SpriteFramesEditor::_copy_pressed() {
  115. ERR_FAIL_COND(!frames->has_animation(edited_anim));
  116. if (tree->get_current() < 0)
  117. return;
  118. Ref<Texture> r = frames->get_frame(edited_anim, tree->get_current());
  119. if (!r.is_valid()) {
  120. return;
  121. }
  122. EditorSettings::get_singleton()->set_resource_clipboard(r);
  123. }
  124. void SpriteFramesEditor::_empty_pressed() {
  125. ERR_FAIL_COND(!frames->has_animation(edited_anim));
  126. int from = -1;
  127. if (tree->get_current() >= 0) {
  128. from = tree->get_current();
  129. sel = from;
  130. } else {
  131. from = frames->get_frame_count(edited_anim);
  132. }
  133. Ref<Texture> r;
  134. undo_redo->create_action(TTR("Add Empty"));
  135. undo_redo->add_do_method(frames, "add_frame", edited_anim, r, from);
  136. undo_redo->add_undo_method(frames, "remove_frame", edited_anim, from);
  137. undo_redo->add_do_method(this, "_update_library");
  138. undo_redo->add_undo_method(this, "_update_library");
  139. undo_redo->commit_action();
  140. }
  141. void SpriteFramesEditor::_empty2_pressed() {
  142. ERR_FAIL_COND(!frames->has_animation(edited_anim));
  143. int from = -1;
  144. if (tree->get_current() >= 0) {
  145. from = tree->get_current();
  146. sel = from;
  147. } else {
  148. from = frames->get_frame_count(edited_anim);
  149. }
  150. Ref<Texture> r;
  151. undo_redo->create_action(TTR("Add Empty"));
  152. undo_redo->add_do_method(frames, "add_frame", edited_anim, r, from + 1);
  153. undo_redo->add_undo_method(frames, "remove_frame", edited_anim, from + 1);
  154. undo_redo->add_do_method(this, "_update_library");
  155. undo_redo->add_undo_method(this, "_update_library");
  156. undo_redo->commit_action();
  157. }
  158. void SpriteFramesEditor::_up_pressed() {
  159. ERR_FAIL_COND(!frames->has_animation(edited_anim));
  160. if (tree->get_current() < 0)
  161. return;
  162. int to_move = tree->get_current();
  163. if (to_move < 1)
  164. return;
  165. sel = to_move;
  166. sel -= 1;
  167. Ref<Texture> r = frames->get_frame(edited_anim, to_move);
  168. undo_redo->create_action(TTR("Delete Resource"));
  169. undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move, frames->get_frame(edited_anim, to_move - 1));
  170. undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move - 1, frames->get_frame(edited_anim, to_move));
  171. undo_redo->add_undo_method(frames, "set_frame", edited_anim, to_move, frames->get_frame(edited_anim, to_move));
  172. undo_redo->add_undo_method(frames, "set_frame", edited_anim, to_move - 1, frames->get_frame(edited_anim, to_move - 1));
  173. undo_redo->add_do_method(this, "_update_library");
  174. undo_redo->add_undo_method(this, "_update_library");
  175. undo_redo->commit_action();
  176. }
  177. void SpriteFramesEditor::_down_pressed() {
  178. ERR_FAIL_COND(!frames->has_animation(edited_anim));
  179. if (tree->get_current() < 0)
  180. return;
  181. int to_move = tree->get_current();
  182. if (to_move < 0 || to_move >= frames->get_frame_count(edited_anim) - 1)
  183. return;
  184. sel = to_move;
  185. sel += 1;
  186. Ref<Texture> r = frames->get_frame(edited_anim, to_move);
  187. undo_redo->create_action(TTR("Delete Resource"));
  188. undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move, frames->get_frame(edited_anim, to_move + 1));
  189. undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move + 1, frames->get_frame(edited_anim, to_move));
  190. undo_redo->add_undo_method(frames, "set_frame", edited_anim, to_move, frames->get_frame(edited_anim, to_move));
  191. undo_redo->add_undo_method(frames, "set_frame", edited_anim, to_move + 1, frames->get_frame(edited_anim, to_move + 1));
  192. undo_redo->add_do_method(this, "_update_library");
  193. undo_redo->add_undo_method(this, "_update_library");
  194. undo_redo->commit_action();
  195. }
  196. void SpriteFramesEditor::_delete_pressed() {
  197. ERR_FAIL_COND(!frames->has_animation(edited_anim));
  198. if (tree->get_current() < 0)
  199. return;
  200. int to_delete = tree->get_current();
  201. if (to_delete < 0 || to_delete >= frames->get_frame_count(edited_anim)) {
  202. return;
  203. }
  204. undo_redo->create_action(TTR("Delete Resource"));
  205. undo_redo->add_do_method(frames, "remove_frame", edited_anim, to_delete);
  206. undo_redo->add_undo_method(frames, "add_frame", edited_anim, frames->get_frame(edited_anim, to_delete), to_delete);
  207. undo_redo->add_do_method(this, "_update_library");
  208. undo_redo->add_undo_method(this, "_update_library");
  209. undo_redo->commit_action();
  210. }
  211. void SpriteFramesEditor::_animation_select() {
  212. if (updating)
  213. return;
  214. TreeItem *selected = animations->get_selected();
  215. ERR_FAIL_COND(!selected);
  216. edited_anim = selected->get_text(0);
  217. _update_library(true);
  218. }
  219. static void _find_anim_sprites(Node *p_node, List<Node *> *r_nodes, Ref<SpriteFrames> p_sfames) {
  220. Node *edited = EditorNode::get_singleton()->get_edited_scene();
  221. if (!edited)
  222. return;
  223. if (p_node != edited && p_node->get_owner() != edited)
  224. return;
  225. {
  226. AnimatedSprite *as = Object::cast_to<AnimatedSprite>(p_node);
  227. if (as && as->get_sprite_frames() == p_sfames) {
  228. r_nodes->push_back(p_node);
  229. }
  230. }
  231. {
  232. AnimatedSprite3D *as = Object::cast_to<AnimatedSprite3D>(p_node);
  233. if (as && as->get_sprite_frames() == p_sfames) {
  234. r_nodes->push_back(p_node);
  235. }
  236. }
  237. for (int i = 0; i < p_node->get_child_count(); i++) {
  238. _find_anim_sprites(p_node->get_child(i), r_nodes, p_sfames);
  239. }
  240. }
  241. void SpriteFramesEditor::_animation_name_edited() {
  242. if (updating)
  243. return;
  244. if (!frames->has_animation(edited_anim))
  245. return;
  246. TreeItem *edited = animations->get_edited();
  247. if (!edited)
  248. return;
  249. String new_name = edited->get_text(0);
  250. if (new_name == String(edited_anim))
  251. return;
  252. new_name = new_name.replace("/", "_").replace(",", " ");
  253. String name = new_name;
  254. int counter = 0;
  255. while (frames->has_animation(name)) {
  256. counter++;
  257. name = new_name + " " + itos(counter);
  258. }
  259. List<Node *> nodes;
  260. _find_anim_sprites(EditorNode::get_singleton()->get_edited_scene(), &nodes, Ref<SpriteFrames>(frames));
  261. undo_redo->create_action(TTR("Rename Animation"));
  262. undo_redo->add_do_method(frames, "rename_animation", edited_anim, name);
  263. undo_redo->add_undo_method(frames, "rename_animation", name, edited_anim);
  264. for (List<Node *>::Element *E = nodes.front(); E; E = E->next()) {
  265. String current = E->get()->call("get_animation");
  266. if (current != edited_anim)
  267. continue;
  268. undo_redo->add_do_method(E->get(), "set_animation", name);
  269. undo_redo->add_undo_method(E->get(), "set_animation", edited_anim);
  270. }
  271. undo_redo->add_do_method(this, "_update_library");
  272. undo_redo->add_undo_method(this, "_update_library");
  273. edited_anim = new_name;
  274. undo_redo->commit_action();
  275. }
  276. void SpriteFramesEditor::_animation_add() {
  277. String name = "New Anim";
  278. int counter = 0;
  279. while (frames->has_animation(name)) {
  280. counter++;
  281. name = "New Anim " + itos(counter);
  282. }
  283. List<Node *> nodes;
  284. _find_anim_sprites(EditorNode::get_singleton()->get_edited_scene(), &nodes, Ref<SpriteFrames>(frames));
  285. undo_redo->create_action(TTR("Add Animation"));
  286. undo_redo->add_do_method(frames, "add_animation", name);
  287. undo_redo->add_undo_method(frames, "remove_animation", name);
  288. undo_redo->add_do_method(this, "_update_library");
  289. undo_redo->add_undo_method(this, "_update_library");
  290. for (List<Node *>::Element *E = nodes.front(); E; E = E->next()) {
  291. String current = E->get()->call("get_animation");
  292. if (frames->has_animation(current))
  293. continue;
  294. undo_redo->add_do_method(E->get(), "set_animation", name);
  295. undo_redo->add_undo_method(E->get(), "set_animation", current);
  296. }
  297. edited_anim = name;
  298. undo_redo->commit_action();
  299. }
  300. void SpriteFramesEditor::_animation_remove() {
  301. //fuck everything
  302. if (updating)
  303. return;
  304. if (!frames->has_animation(edited_anim))
  305. return;
  306. undo_redo->create_action(TTR("Remove Animation"));
  307. undo_redo->add_do_method(frames, "remove_animation", edited_anim);
  308. undo_redo->add_undo_method(frames, "add_animation", edited_anim);
  309. undo_redo->add_undo_method(frames, "set_animation_speed", edited_anim, frames->get_animation_speed(edited_anim));
  310. undo_redo->add_undo_method(frames, "set_animation_loop", edited_anim, frames->get_animation_loop(edited_anim));
  311. int fc = frames->get_frame_count(edited_anim);
  312. for (int i = 0; i < fc; i++) {
  313. Ref<Texture> frame = frames->get_frame(edited_anim, i);
  314. undo_redo->add_undo_method(frames, "add_frame", edited_anim, frame);
  315. }
  316. undo_redo->add_do_method(this, "_update_library");
  317. undo_redo->add_undo_method(this, "_update_library");
  318. undo_redo->commit_action();
  319. }
  320. void SpriteFramesEditor::_animation_loop_changed() {
  321. if (updating)
  322. return;
  323. undo_redo->create_action(TTR("Change Animation Loop"));
  324. undo_redo->add_do_method(frames, "set_animation_loop", edited_anim, anim_loop->is_pressed());
  325. undo_redo->add_undo_method(frames, "set_animation_loop", edited_anim, frames->get_animation_loop(edited_anim));
  326. undo_redo->add_do_method(this, "_update_library", true);
  327. undo_redo->add_undo_method(this, "_update_library", true);
  328. undo_redo->commit_action();
  329. }
  330. void SpriteFramesEditor::_animation_fps_changed(double p_value) {
  331. if (updating)
  332. return;
  333. undo_redo->create_action(TTR("Change Animation FPS"), UndoRedo::MERGE_ENDS);
  334. undo_redo->add_do_method(frames, "set_animation_speed", edited_anim, p_value);
  335. undo_redo->add_undo_method(frames, "set_animation_speed", edited_anim, frames->get_animation_speed(edited_anim));
  336. undo_redo->add_do_method(this, "_update_library", true);
  337. undo_redo->add_undo_method(this, "_update_library", true);
  338. undo_redo->commit_action();
  339. }
  340. void SpriteFramesEditor::_update_library(bool p_skip_selector) {
  341. updating = true;
  342. if (!p_skip_selector) {
  343. animations->clear();
  344. TreeItem *anim_root = animations->create_item();
  345. List<StringName> anim_names;
  346. anim_names.sort_custom<StringName::AlphCompare>();
  347. frames->get_animation_list(&anim_names);
  348. anim_names.sort_custom<StringName::AlphCompare>();
  349. for (List<StringName>::Element *E = anim_names.front(); E; E = E->next()) {
  350. String name = E->get();
  351. TreeItem *it = animations->create_item(anim_root);
  352. it->set_metadata(0, name);
  353. it->set_text(0, name);
  354. it->set_editable(0, true);
  355. if (E->get() == edited_anim) {
  356. it->select(0);
  357. }
  358. }
  359. }
  360. tree->clear();
  361. if (!frames->has_animation(edited_anim)) {
  362. updating = false;
  363. return;
  364. }
  365. if (sel >= frames->get_frame_count(edited_anim))
  366. sel = frames->get_frame_count(edited_anim) - 1;
  367. else if (sel < 0 && frames->get_frame_count(edited_anim))
  368. sel = 0;
  369. for (int i = 0; i < frames->get_frame_count(edited_anim); i++) {
  370. String name;
  371. Ref<Texture> icon;
  372. if (frames->get_frame(edited_anim, i).is_null()) {
  373. name = itos(i) + ": " + TTR("(empty)");
  374. } else {
  375. name = itos(i) + ": " + frames->get_frame(edited_anim, i)->get_name();
  376. icon = frames->get_frame(edited_anim, i);
  377. }
  378. tree->add_item(name, icon);
  379. if (frames->get_frame(edited_anim, i).is_valid())
  380. tree->set_item_tooltip(tree->get_item_count() - 1, frames->get_frame(edited_anim, i)->get_path());
  381. if (sel == i)
  382. tree->select(tree->get_item_count() - 1);
  383. }
  384. anim_speed->set_value(frames->get_animation_speed(edited_anim));
  385. anim_loop->set_pressed(frames->get_animation_loop(edited_anim));
  386. updating = false;
  387. //player->add_resource("default",resource);
  388. }
  389. void SpriteFramesEditor::edit(SpriteFrames *p_frames) {
  390. if (frames == p_frames)
  391. return;
  392. frames = p_frames;
  393. if (p_frames) {
  394. if (!p_frames->has_animation(edited_anim)) {
  395. List<StringName> anim_names;
  396. frames->get_animation_list(&anim_names);
  397. anim_names.sort_custom<StringName::AlphCompare>();
  398. if (anim_names.size()) {
  399. edited_anim = anim_names.front()->get();
  400. } else {
  401. edited_anim = StringName();
  402. }
  403. }
  404. _update_library();
  405. } else {
  406. hide();
  407. //set_physics_process(false);
  408. }
  409. }
  410. Variant SpriteFramesEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
  411. if (!frames->has_animation(edited_anim))
  412. return false;
  413. int idx = tree->get_item_at_position(p_point, true);
  414. if (idx < 0 || idx >= frames->get_frame_count(edited_anim))
  415. return Variant();
  416. RES frame = frames->get_frame(edited_anim, idx);
  417. if (frame.is_null())
  418. return Variant();
  419. return EditorNode::get_singleton()->drag_resource(frame, p_from);
  420. }
  421. bool SpriteFramesEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
  422. Dictionary d = p_data;
  423. if (!d.has("type"))
  424. return false;
  425. if (d.has("from") && (Object *)(d["from"]) == tree)
  426. return false;
  427. if (String(d["type"]) == "resource" && d.has("resource")) {
  428. RES r = d["resource"];
  429. Ref<Texture> texture = r;
  430. if (texture.is_valid()) {
  431. return true;
  432. }
  433. }
  434. if (String(d["type"]) == "files") {
  435. Vector<String> files = d["files"];
  436. if (files.size() == 0)
  437. return false;
  438. for (int i = 0; i < files.size(); i++) {
  439. String file = files[0];
  440. String ftype = EditorFileSystem::get_singleton()->get_file_type(file);
  441. if (!ClassDB::is_parent_class(ftype, "Texture")) {
  442. return false;
  443. }
  444. }
  445. return true;
  446. }
  447. return false;
  448. }
  449. void SpriteFramesEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
  450. if (!can_drop_data_fw(p_point, p_data, p_from))
  451. return;
  452. Dictionary d = p_data;
  453. if (!d.has("type"))
  454. return;
  455. int at_pos = tree->get_item_at_position(p_point, true);
  456. if (String(d["type"]) == "resource" && d.has("resource")) {
  457. RES r = d["resource"];
  458. Ref<Texture> texture = r;
  459. if (texture.is_valid()) {
  460. undo_redo->create_action(TTR("Add Frame"));
  461. undo_redo->add_do_method(frames, "add_frame", edited_anim, texture, at_pos == -1 ? -1 : at_pos);
  462. undo_redo->add_undo_method(frames, "remove_frame", edited_anim, at_pos == -1 ? frames->get_frame_count(edited_anim) : at_pos);
  463. undo_redo->add_do_method(this, "_update_library");
  464. undo_redo->add_undo_method(this, "_update_library");
  465. undo_redo->commit_action();
  466. }
  467. }
  468. if (String(d["type"]) == "files") {
  469. PoolVector<String> files = d["files"];
  470. _file_load_request(files, at_pos);
  471. }
  472. }
  473. void SpriteFramesEditor::_bind_methods() {
  474. ClassDB::bind_method(D_METHOD("_gui_input"), &SpriteFramesEditor::_gui_input);
  475. ClassDB::bind_method(D_METHOD("_load_pressed"), &SpriteFramesEditor::_load_pressed);
  476. ClassDB::bind_method(D_METHOD("_empty_pressed"), &SpriteFramesEditor::_empty_pressed);
  477. ClassDB::bind_method(D_METHOD("_empty2_pressed"), &SpriteFramesEditor::_empty2_pressed);
  478. ClassDB::bind_method(D_METHOD("_delete_pressed"), &SpriteFramesEditor::_delete_pressed);
  479. ClassDB::bind_method(D_METHOD("_copy_pressed"), &SpriteFramesEditor::_copy_pressed);
  480. ClassDB::bind_method(D_METHOD("_paste_pressed"), &SpriteFramesEditor::_paste_pressed);
  481. ClassDB::bind_method(D_METHOD("_file_load_request", "files", "at_position"), &SpriteFramesEditor::_file_load_request, DEFVAL(-1));
  482. ClassDB::bind_method(D_METHOD("_update_library", "skipsel"), &SpriteFramesEditor::_update_library, DEFVAL(false));
  483. ClassDB::bind_method(D_METHOD("_up_pressed"), &SpriteFramesEditor::_up_pressed);
  484. ClassDB::bind_method(D_METHOD("_down_pressed"), &SpriteFramesEditor::_down_pressed);
  485. ClassDB::bind_method(D_METHOD("_animation_select"), &SpriteFramesEditor::_animation_select);
  486. ClassDB::bind_method(D_METHOD("_animation_name_edited"), &SpriteFramesEditor::_animation_name_edited);
  487. ClassDB::bind_method(D_METHOD("_animation_add"), &SpriteFramesEditor::_animation_add);
  488. ClassDB::bind_method(D_METHOD("_animation_remove"), &SpriteFramesEditor::_animation_remove);
  489. ClassDB::bind_method(D_METHOD("_animation_loop_changed"), &SpriteFramesEditor::_animation_loop_changed);
  490. ClassDB::bind_method(D_METHOD("_animation_fps_changed"), &SpriteFramesEditor::_animation_fps_changed);
  491. ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &SpriteFramesEditor::get_drag_data_fw);
  492. ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &SpriteFramesEditor::can_drop_data_fw);
  493. ClassDB::bind_method(D_METHOD("drop_data_fw"), &SpriteFramesEditor::drop_data_fw);
  494. }
  495. SpriteFramesEditor::SpriteFramesEditor() {
  496. //add_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_stylebox("panel","Panel"));
  497. split = memnew(HSplitContainer);
  498. add_child(split);
  499. VBoxContainer *vbc_animlist = memnew(VBoxContainer);
  500. split->add_child(vbc_animlist);
  501. vbc_animlist->set_custom_minimum_size(Size2(150, 0) * EDSCALE);
  502. //vbc_animlist->set_v_size_flags(SIZE_EXPAND_FILL);
  503. VBoxContainer *sub_vb = memnew(VBoxContainer);
  504. vbc_animlist->add_margin_child(TTR("Animations"), sub_vb, true);
  505. sub_vb->set_v_size_flags(SIZE_EXPAND_FILL);
  506. HBoxContainer *hbc_animlist = memnew(HBoxContainer);
  507. sub_vb->add_child(hbc_animlist);
  508. new_anim = memnew(Button);
  509. new_anim->set_flat(true);
  510. hbc_animlist->add_child(new_anim);
  511. new_anim->set_h_size_flags(SIZE_EXPAND_FILL);
  512. new_anim->connect("pressed", this, "_animation_add");
  513. remove_anim = memnew(Button);
  514. remove_anim->set_flat(true);
  515. hbc_animlist->add_child(remove_anim);
  516. remove_anim->connect("pressed", this, "_animation_remove");
  517. animations = memnew(Tree);
  518. sub_vb->add_child(animations);
  519. animations->set_v_size_flags(SIZE_EXPAND_FILL);
  520. animations->set_hide_root(true);
  521. animations->connect("cell_selected", this, "_animation_select");
  522. animations->connect("item_edited", this, "_animation_name_edited");
  523. animations->set_allow_reselect(true);
  524. anim_speed = memnew(SpinBox);
  525. vbc_animlist->add_margin_child(TTR("Speed (FPS):"), anim_speed);
  526. anim_speed->set_min(0);
  527. anim_speed->set_max(100);
  528. anim_speed->set_step(0.01);
  529. anim_speed->connect("value_changed", this, "_animation_fps_changed");
  530. anim_loop = memnew(CheckButton);
  531. anim_loop->set_text(TTR("Loop"));
  532. vbc_animlist->add_child(anim_loop);
  533. anim_loop->connect("pressed", this, "_animation_loop_changed");
  534. VBoxContainer *vbc = memnew(VBoxContainer);
  535. split->add_child(vbc);
  536. vbc->set_h_size_flags(SIZE_EXPAND_FILL);
  537. sub_vb = memnew(VBoxContainer);
  538. vbc->add_margin_child(TTR("Animation Frames"), sub_vb, true);
  539. HBoxContainer *hbc = memnew(HBoxContainer);
  540. sub_vb->add_child(hbc);
  541. //animations = memnew( ItemList );
  542. load = memnew(Button);
  543. load->set_flat(true);
  544. load->set_tooltip(TTR("Load Resource"));
  545. hbc->add_child(load);
  546. copy = memnew(Button);
  547. copy->set_text(TTR("Copy"));
  548. hbc->add_child(copy);
  549. paste = memnew(Button);
  550. paste->set_text(TTR("Paste"));
  551. hbc->add_child(paste);
  552. empty = memnew(Button);
  553. empty->set_text(TTR("Insert Empty (Before)"));
  554. hbc->add_child(empty);
  555. empty2 = memnew(Button);
  556. empty2->set_text(TTR("Insert Empty (After)"));
  557. hbc->add_child(empty2);
  558. move_up = memnew(Button);
  559. move_up->set_text(TTR("Move (Before)"));
  560. hbc->add_child(move_up);
  561. move_down = memnew(Button);
  562. move_down->set_text(TTR("Move (After)"));
  563. hbc->add_child(move_down);
  564. _delete = memnew(Button);
  565. _delete->set_flat(true);
  566. hbc->add_child(_delete);
  567. file = memnew(EditorFileDialog);
  568. add_child(file);
  569. tree = memnew(ItemList);
  570. tree->set_v_size_flags(SIZE_EXPAND_FILL);
  571. tree->set_icon_mode(ItemList::ICON_MODE_TOP);
  572. int thumbnail_size = 96;
  573. tree->set_max_columns(0);
  574. tree->set_icon_mode(ItemList::ICON_MODE_TOP);
  575. tree->set_fixed_column_width(thumbnail_size * 3 / 2);
  576. tree->set_max_text_lines(2);
  577. tree->set_fixed_icon_size(Size2(thumbnail_size, thumbnail_size));
  578. //tree->set_min_icon_size(Size2(thumbnail_size,thumbnail_size));
  579. tree->set_drag_forwarding(this);
  580. sub_vb->add_child(tree);
  581. dialog = memnew(AcceptDialog);
  582. add_child(dialog);
  583. load->connect("pressed", this, "_load_pressed");
  584. _delete->connect("pressed", this, "_delete_pressed");
  585. copy->connect("pressed", this, "_copy_pressed");
  586. paste->connect("pressed", this, "_paste_pressed");
  587. empty->connect("pressed", this, "_empty_pressed");
  588. empty2->connect("pressed", this, "_empty2_pressed");
  589. move_up->connect("pressed", this, "_up_pressed");
  590. move_down->connect("pressed", this, "_down_pressed");
  591. file->connect("files_selected", this, "_file_load_request");
  592. loading_scene = false;
  593. sel = -1;
  594. updating = false;
  595. edited_anim = "default";
  596. }
  597. void SpriteFramesEditorPlugin::edit(Object *p_object) {
  598. frames_editor->set_undo_redo(&get_undo_redo());
  599. SpriteFrames *s = Object::cast_to<SpriteFrames>(p_object);
  600. if (!s)
  601. return;
  602. frames_editor->edit(s);
  603. }
  604. bool SpriteFramesEditorPlugin::handles(Object *p_object) const {
  605. return p_object->is_class("SpriteFrames");
  606. }
  607. void SpriteFramesEditorPlugin::make_visible(bool p_visible) {
  608. if (p_visible) {
  609. button->show();
  610. editor->make_bottom_panel_item_visible(frames_editor);
  611. //frames_editor->set_process(true);
  612. } else {
  613. button->hide();
  614. if (frames_editor->is_visible_in_tree())
  615. editor->hide_bottom_panel();
  616. //frames_editor->set_process(false);
  617. }
  618. }
  619. SpriteFramesEditorPlugin::SpriteFramesEditorPlugin(EditorNode *p_node) {
  620. editor = p_node;
  621. frames_editor = memnew(SpriteFramesEditor);
  622. frames_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
  623. button = editor->add_bottom_panel_item("SpriteFrames", frames_editor);
  624. button->hide();
  625. }
  626. SpriteFramesEditorPlugin::~SpriteFramesEditorPlugin() {
  627. }