1 /*************************************************************************/
2 /* animation_player_editor_plugin.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2019 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 "animation_player_editor_plugin.h"
31 #include "editor/animation_editor.h"
32 #include "editor/editor_settings.h"
33 #include "globals.h"
34 #include "io/resource_loader.h"
35 #include "io/resource_saver.h"
36 #include "os/keyboard.h"
37
_node_removed(Node * p_node)38 void AnimationPlayerEditor::_node_removed(Node *p_node) {
39
40 if (player && player == p_node) {
41 player = NULL;
42
43 set_process(false);
44
45 key_editor->set_animation(Ref<Animation>());
46 key_editor->set_root(NULL);
47 key_editor->show_select_node_warning(true);
48 _update_player();
49 //editor->animation_editor_make_visible(false);
50 }
51 }
52
_input_event(InputEvent p_event)53 void AnimationPlayerEditor::_input_event(InputEvent p_event) {
54 }
55
_notification(int p_what)56 void AnimationPlayerEditor::_notification(int p_what) {
57
58 if (p_what == NOTIFICATION_PROCESS) {
59
60 if (!player)
61 return;
62
63 updating = true;
64
65 if (player->is_playing()) {
66
67 {
68 String animname = player->get_current_animation();
69
70 if (player->has_animation(animname)) {
71 Ref<Animation> anim = player->get_animation(animname);
72 if (!anim.is_null()) {
73
74 frame->set_max(anim->get_length());
75 }
76 }
77 }
78 frame->set_val(player->get_current_animation_pos());
79 key_editor->set_anim_pos(player->get_current_animation_pos());
80 EditorNode::get_singleton()->get_property_editor()->refresh();
81
82 } else if (last_active) {
83 //need the last frame after it stopped
84
85 frame->set_val(player->get_current_animation_pos());
86 }
87
88 last_active = player->is_playing();
89 //seek->set_val(player->get_pos());
90 updating = false;
91 }
92
93 if (p_what == NOTIFICATION_ENTER_TREE) {
94
95 // editor->connect("hide_animation_player_editors",this,"_hide_anim_editors");
96 add_anim->set_icon(get_icon("New", "EditorIcons"));
97 rename_anim->set_icon(get_icon("Rename", "EditorIcons"));
98 duplicate_anim->set_icon(get_icon("Duplicate", "EditorIcons"));
99 autoplay->set_icon(get_icon("AutoPlay", "EditorIcons"));
100 load_anim->set_icon(get_icon("Folder", "EditorIcons"));
101 save_anim->set_icon(get_icon("Save", "EditorIcons"));
102 save_anim->get_popup()->connect("item_pressed", this, "_animation_save_menu");
103 remove_anim->set_icon(get_icon("Remove", "EditorIcons"));
104
105 blend_anim->set_icon(get_icon("Blend", "EditorIcons"));
106 play->set_icon(get_icon("PlayStart", "EditorIcons"));
107 play_from->set_icon(get_icon("Play", "EditorIcons"));
108 play_bw->set_icon(get_icon("PlayStartBackwards", "EditorIcons"));
109 play_bw_from->set_icon(get_icon("PlayBackwards", "EditorIcons"));
110
111 autoplay_icon = get_icon("AutoPlay", "EditorIcons");
112 stop->set_icon(get_icon("Stop", "EditorIcons"));
113 resource_edit_anim->set_icon(get_icon("EditResource", "EditorIcons"));
114 pin->set_icon(get_icon("Pin", "EditorIcons"));
115 tool_anim->set_icon(get_icon("Tools", "EditorIcons"));
116 tool_anim->get_popup()->connect("item_pressed", this, "_animation_tool_menu");
117
118 blend_editor.next->connect("item_selected", this, "_blend_editor_next_changed");
119
120 nodename->set_icon(get_icon("AnimationPlayer", "EditorIcons"));
121
122 /*
123 anim_editor_load->set_normal_texture( get_icon("AnimGet","EditorIcons"));
124 anim_editor_store->set_normal_texture( get_icon("AnimSet","EditorIcons"));
125 anim_editor_load->set_pressed_texture( get_icon("AnimGet","EditorIcons"));
126 anim_editor_store->set_pressed_texture( get_icon("AnimSet","EditorIcons"));
127 anim_editor_load->set_hover_texture( get_icon("AnimGetHl","EditorIcons"));
128 anim_editor_store->set_hover_texture( get_icon("AnimSetHl","EditorIcons"));
129 */
130
131 get_tree()->connect("node_removed", this, "_node_removed");
132 }
133 }
134
_autoplay_pressed()135 void AnimationPlayerEditor::_autoplay_pressed() {
136
137 if (updating)
138 return;
139 if (animation->get_item_count() == 0) {
140 return;
141 }
142
143 String current = animation->get_item_text(animation->get_selected());
144 if (player->get_autoplay() == current) {
145 //unset
146 undo_redo->create_action(TTR("Toggle Autoplay"));
147 undo_redo->add_do_method(player, "set_autoplay", "");
148 undo_redo->add_undo_method(player, "set_autoplay", player->get_autoplay());
149 undo_redo->add_do_method(this, "_animation_player_changed", player);
150 undo_redo->add_undo_method(this, "_animation_player_changed", player);
151 undo_redo->commit_action();
152
153 } else {
154 //set
155 undo_redo->create_action(TTR("Toggle Autoplay"));
156 undo_redo->add_do_method(player, "set_autoplay", current);
157 undo_redo->add_undo_method(player, "set_autoplay", player->get_autoplay());
158 undo_redo->add_do_method(this, "_animation_player_changed", player);
159 undo_redo->add_undo_method(this, "_animation_player_changed", player);
160 undo_redo->commit_action();
161 }
162 }
163
_play_pressed()164 void AnimationPlayerEditor::_play_pressed() {
165
166 String current;
167 if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) {
168
169 current = animation->get_item_text(animation->get_selected());
170 }
171
172 if (current != "") {
173
174 if (current == player->get_current_animation())
175 player->stop(); //so it wont blend with itself
176 player->play(current);
177 }
178
179 //unstop
180 stop->set_pressed(false);
181 //unpause
182 //pause->set_pressed(false);
183 }
184
_play_from_pressed()185 void AnimationPlayerEditor::_play_from_pressed() {
186
187 String current;
188 if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) {
189
190 current = animation->get_item_text(animation->get_selected());
191 }
192
193 if (current != "") {
194
195 float time = player->get_current_animation_pos();
196
197 if (current == player->get_current_animation() && player->is_playing()) {
198
199 player->stop(); //so it wont blend with itself
200 }
201
202 player->play(current);
203 player->seek(time);
204 }
205
206 //unstop
207 stop->set_pressed(false);
208 //unpause
209 //pause->set_pressed(false);
210 }
211
_play_bw_pressed()212 void AnimationPlayerEditor::_play_bw_pressed() {
213
214 String current;
215 if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) {
216
217 current = animation->get_item_text(animation->get_selected());
218 }
219
220 if (current != "") {
221
222 if (current == player->get_current_animation())
223 player->stop(); //so it wont blend with itself
224 player->play(current, -1, -1, true);
225 }
226
227 //unstop
228 stop->set_pressed(false);
229 //unpause
230 //pause->set_pressed(false);
231 }
232
_play_bw_from_pressed()233 void AnimationPlayerEditor::_play_bw_from_pressed() {
234
235 String current;
236 if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) {
237
238 current = animation->get_item_text(animation->get_selected());
239 }
240
241 if (current != "") {
242
243 float time = player->get_current_animation_pos();
244 if (current == player->get_current_animation())
245 player->stop(); //so it wont blend with itself
246
247 player->play(current, -1, -1, true);
248 player->seek(time);
249 }
250
251 //unstop
252 stop->set_pressed(false);
253 //unpause
254 //pause->set_pressed(false);
255 }
_stop_pressed()256 void AnimationPlayerEditor::_stop_pressed() {
257
258 if (!player) {
259 return;
260 }
261
262 player->stop(false);
263 play->set_pressed(false);
264 stop->set_pressed(true);
265 //pause->set_pressed(false);
266 //player->set_pause(false);
267 }
268
_pause_pressed()269 void AnimationPlayerEditor::_pause_pressed() {
270
271 //player->set_pause( pause->is_pressed() );
272 }
_animation_selected(int p_which)273 void AnimationPlayerEditor::_animation_selected(int p_which) {
274
275 if (updating)
276 return;
277 // when selecting an animation, the idea is that the only interesting behavior
278 // ui-wise is that it should play/blend the next one if currently playing
279 String current;
280 if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) {
281
282 current = animation->get_item_text(animation->get_selected());
283 }
284
285 if (current != "") {
286
287 player->set_current_animation(current);
288
289 Ref<Animation> anim = player->get_animation(current);
290 {
291
292 key_editor->set_animation(anim);
293 Node *root = player->get_node(player->get_root());
294 if (root) {
295 key_editor->set_root(root);
296 }
297 }
298 frame->set_max(anim->get_length());
299 if (anim->get_step())
300 frame->set_step(anim->get_step());
301 else
302 frame->set_step(0.00001);
303
304 } else {
305 key_editor->set_animation(Ref<Animation>());
306 key_editor->set_root(NULL);
307 }
308
309 autoplay->set_pressed(current == player->get_autoplay());
310 }
311
_animation_new()312 void AnimationPlayerEditor::_animation_new() {
313
314 renaming = false;
315 name_title->set_text(TTR("New Animation Name:"));
316
317 int count = 1;
318 String base = TTR("New Anim");
319 while (true) {
320 String attempt = base;
321 if (count > 1)
322 attempt += " (" + itos(count) + ")";
323 if (player->has_animation(attempt)) {
324 count++;
325 continue;
326 }
327 base = attempt;
328 break;
329 }
330
331 name->set_text(base);
332 name_dialog->popup_centered(Size2(300, 90));
333 name->select_all();
334 name->grab_focus();
335 }
_animation_rename()336 void AnimationPlayerEditor::_animation_rename() {
337
338 if (animation->get_item_count() == 0)
339 return;
340 int selected = animation->get_selected();
341 String selected_name = animation->get_item_text(selected);
342
343 name_title->set_text(TTR("Change Animation Name:"));
344 name->set_text(selected_name);
345 renaming = true;
346 name_dialog->popup_centered(Size2(300, 90));
347 name->select_all();
348 name->grab_focus();
349 }
_animation_load()350 void AnimationPlayerEditor::_animation_load() {
351 ERR_FAIL_COND(!player);
352 file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
353 file->clear_filters();
354 List<String> extensions;
355
356 ResourceLoader::get_recognized_extensions_for_type("Animation", &extensions);
357 for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
358
359 file->add_filter("*." + E->get() + " ; " + E->get().to_upper());
360 }
361
362 file->popup_centered_ratio();
363 current_option = RESOURCE_LOAD;
364 }
365
_animation_save_in_path(const Ref<Resource> & p_resource,const String & p_path)366 void AnimationPlayerEditor::_animation_save_in_path(const Ref<Resource> &p_resource, const String &p_path) {
367
368 int flg = 0;
369 if (EditorSettings::get_singleton()->get("on_save/compress_binary_resources"))
370 flg |= ResourceSaver::FLAG_COMPRESS;
371 //if (EditorSettings::get_singleton()->get("on_save/save_paths_as_relative"))
372 // flg |= ResourceSaver::FLAG_RELATIVE_PATHS;
373
374 String path = Globals::get_singleton()->localize_path(p_path);
375 Error err = ResourceSaver::save(path, p_resource, flg | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS);
376
377 if (err != OK) {
378 accept->set_text(TTR("Error saving resource!"));
379 accept->popup_centered_minsize();
380 return;
381 }
382 // EditorFileSystem::get_singleton()->update_file(path,p_resource->get_type());
383
384 ((Resource *)p_resource.ptr())->set_path(path);
385 editor->emit_signal("resource_saved", p_resource);
386 }
387
_animation_save(const Ref<Resource> & p_resource)388 void AnimationPlayerEditor::_animation_save(const Ref<Resource> &p_resource) {
389
390 if (p_resource->get_path().is_resource_file()) {
391 _animation_save_in_path(p_resource, p_resource->get_path());
392 } else {
393 _animation_save_as(p_resource);
394 }
395 }
396
_animation_save_as(const Ref<Resource> & p_resource)397 void AnimationPlayerEditor::_animation_save_as(const Ref<Resource> &p_resource) {
398
399 file->set_mode(EditorFileDialog::MODE_SAVE_FILE);
400
401 List<String> extensions;
402 ResourceSaver::get_recognized_extensions(p_resource, &extensions);
403 file->clear_filters();
404 for (int i = 0; i < extensions.size(); i++) {
405
406 file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
407 }
408
409 //file->set_current_path(current_path);
410 if (p_resource->get_path() != "") {
411 file->set_current_path(p_resource->get_path());
412 if (extensions.size()) {
413 String ext = p_resource->get_path().extension().to_lower();
414 if (extensions.find(ext) == NULL) {
415 file->set_current_path(p_resource->get_path().replacen("." + ext, "." + extensions.front()->get()));
416 }
417 }
418 } else {
419
420 String existing;
421 if (extensions.size()) {
422 existing = "new_" + p_resource->get_type().to_lower() + "." + extensions.front()->get().to_lower();
423 }
424 file->set_current_path(existing);
425 }
426 file->popup_centered_ratio();
427 file->set_title(TTR("Save Resource As.."));
428 current_option = RESOURCE_SAVE;
429 }
430
_animation_remove()431 void AnimationPlayerEditor::_animation_remove() {
432
433 if (animation->get_item_count() == 0)
434 return;
435
436 delete_dialog->set_text(TTR("Delete Animation?"));
437 delete_dialog->popup_centered_minsize();
438 }
439
_animation_remove_confirmed()440 void AnimationPlayerEditor::_animation_remove_confirmed() {
441
442 String current = animation->get_item_text(animation->get_selected());
443 Ref<Animation> anim = player->get_animation(current);
444
445 undo_redo->create_action(TTR("Remove Animation"));
446 undo_redo->add_do_method(player, "remove_animation", current);
447 undo_redo->add_undo_method(player, "add_animation", current, anim);
448 undo_redo->add_do_method(this, "_animation_player_changed", player);
449 undo_redo->add_undo_method(this, "_animation_player_changed", player);
450 undo_redo->commit_action();
451 }
452
_select_anim_by_name(const String & p_anim)453 void AnimationPlayerEditor::_select_anim_by_name(const String &p_anim) {
454
455 int idx = -1;
456 for (int i = 0; i < animation->get_item_count(); i++) {
457
458 if (animation->get_item_text(i) == p_anim) {
459
460 idx = i;
461 break;
462 }
463 }
464
465 ERR_FAIL_COND(idx == -1);
466
467 animation->select(idx);
468
469 _animation_selected(idx);
470 }
471
_animation_name_edited()472 void AnimationPlayerEditor::_animation_name_edited() {
473
474 player->stop();
475
476 String new_name = name->get_text();
477 if (new_name == "" || new_name.find(":") != -1 || new_name.find("/") != -1) {
478 error_dialog->set_text(TTR("ERROR: Invalid animation name!"));
479 error_dialog->popup_centered_minsize();
480 return;
481 }
482
483 if (renaming && animation->get_item_count() > 0 && animation->get_item_text(animation->get_selected()) == new_name) {
484 name_dialog->hide();
485 return;
486 }
487
488 if (player->has_animation(new_name)) {
489 error_dialog->set_text(TTR("ERROR: Animation name already exists!"));
490 error_dialog->popup_centered_minsize();
491 return;
492 }
493
494 if (renaming) {
495 String current = animation->get_item_text(animation->get_selected());
496 Ref<Animation> anim = player->get_animation(current);
497
498 undo_redo->create_action(TTR("Rename Animation"));
499 undo_redo->add_do_method(player, "rename_animation", current, new_name);
500 undo_redo->add_do_method(anim.ptr(), "set_name", new_name);
501 undo_redo->add_undo_method(player, "rename_animation", new_name, current);
502 undo_redo->add_undo_method(anim.ptr(), "set_name", current);
503 undo_redo->add_do_method(this, "_animation_player_changed", player);
504 undo_redo->add_undo_method(this, "_animation_player_changed", player);
505 undo_redo->commit_action();
506
507 _select_anim_by_name(new_name);
508
509 } else {
510
511 Ref<Animation> new_anim = Ref<Animation>(memnew(Animation));
512 new_anim->set_name(new_name);
513
514 undo_redo->create_action(TTR("Add Animation"));
515 undo_redo->add_do_method(player, "add_animation", new_name, new_anim);
516 undo_redo->add_undo_method(player, "remove_animation", new_name);
517 undo_redo->add_do_method(this, "_animation_player_changed", player);
518 undo_redo->add_undo_method(this, "_animation_player_changed", player);
519 undo_redo->commit_action();
520
521 _select_anim_by_name(new_name);
522 }
523
524 name_dialog->hide();
525 }
526
_blend_editor_next_changed(const int p_idx)527 void AnimationPlayerEditor::_blend_editor_next_changed(const int p_idx) {
528
529 if (animation->get_item_count() == 0)
530 return;
531
532 String current = animation->get_item_text(animation->get_selected());
533
534 undo_redo->create_action(TTR("Blend Next Changed"));
535 undo_redo->add_do_method(player, "animation_set_next", current, blend_editor.next->get_item_text(p_idx));
536 undo_redo->add_undo_method(player, "animation_set_next", current, player->animation_get_next(current));
537 undo_redo->add_do_method(this, "_animation_player_changed", player);
538 undo_redo->add_undo_method(this, "_animation_player_changed", player);
539 undo_redo->commit_action();
540 }
541
_animation_blend()542 void AnimationPlayerEditor::_animation_blend() {
543
544 if (updating_blends)
545 return;
546
547 blend_editor.tree->clear();
548
549 if (animation->get_item_count() == 0)
550 return;
551
552 String current = animation->get_item_text(animation->get_selected());
553
554 blend_editor.dialog->popup_centered(Size2(400, 400));
555
556 blend_editor.tree->set_hide_root(true);
557 blend_editor.tree->set_column_min_width(0, 10);
558 blend_editor.tree->set_column_min_width(1, 3);
559
560 List<StringName> anims;
561 player->get_animation_list(&anims);
562 TreeItem *root = blend_editor.tree->create_item();
563 updating_blends = true;
564
565 int i = 0;
566 bool anim_found = false;
567 blend_editor.next->clear();
568 blend_editor.next->add_item("", i);
569
570 for (List<StringName>::Element *E = anims.front(); E; E = E->next()) {
571
572 String to = E->get();
573 TreeItem *blend = blend_editor.tree->create_item(root);
574 blend->set_editable(0, false);
575 blend->set_editable(1, true);
576 blend->set_text(0, to);
577 blend->set_cell_mode(1, TreeItem::CELL_MODE_RANGE);
578 blend->set_range_config(1, 0, 3600, 0.001);
579 blend->set_range(1, player->get_blend_time(current, to));
580
581 i++;
582 blend_editor.next->add_item(to, i);
583 if (to == player->animation_get_next(current)) {
584 blend_editor.next->select(i);
585 anim_found = true;
586 }
587 }
588
589 // make sure we reset it else it becomes out of sync and could contain a deleted animation
590 if (!anim_found) {
591 blend_editor.next->select(0);
592 player->animation_set_next(current, blend_editor.next->get_item_text(0));
593 }
594
595 updating_blends = false;
596 }
597
_blend_edited()598 void AnimationPlayerEditor::_blend_edited() {
599
600 if (updating_blends)
601 return;
602
603 if (animation->get_item_count() == 0)
604 return;
605
606 String current = animation->get_item_text(animation->get_selected());
607
608 TreeItem *selected = blend_editor.tree->get_edited();
609 if (!selected)
610 return;
611
612 updating_blends = true;
613 String to = selected->get_text(0);
614 float blend_time = selected->get_range(1);
615 float prev_blend_time = player->get_blend_time(current, to);
616
617 undo_redo->create_action(TTR("Change Blend Time"));
618 undo_redo->add_do_method(player, "set_blend_time", current, to, blend_time);
619 undo_redo->add_undo_method(player, "set_blend_time", current, to, prev_blend_time);
620 undo_redo->add_do_method(this, "_animation_player_changed", player);
621 undo_redo->add_undo_method(this, "_animation_player_changed", player);
622 undo_redo->commit_action();
623 updating_blends = false;
624 }
625
ensure_visibility()626 void AnimationPlayerEditor::ensure_visibility() {
627
628 if (player && pin->is_pressed())
629 return; // another player is pinned, don't reset
630
631 _animation_edit();
632 }
633
get_state() const634 Dictionary AnimationPlayerEditor::get_state() const {
635
636 Dictionary d;
637
638 d["visible"] = is_visible();
639 if (EditorNode::get_singleton()->get_edited_scene() && is_visible() && player) {
640 d["player"] = EditorNode::get_singleton()->get_edited_scene()->get_path_to(player);
641 d["animation"] = player->get_current_animation();
642 }
643
644 return d;
645 }
set_state(const Dictionary & p_state)646 void AnimationPlayerEditor::set_state(const Dictionary &p_state) {
647
648 if (p_state.has("visible") && p_state["visible"]) {
649
650 if (!EditorNode::get_singleton()->get_edited_scene())
651 return;
652
653 Node *n = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["player"]);
654 if (n && n->cast_to<AnimationPlayer>() && EditorNode::get_singleton()->get_editor_selection()->is_selected(n)) {
655 player = n->cast_to<AnimationPlayer>();
656 _update_player();
657 show();
658 set_process(true);
659 ensure_visibility();
660 // EditorNode::get_singleton()->animation_panel_make_visible(true);
661
662 if (p_state.has("animation")) {
663 String anim = p_state["animation"];
664 _select_anim_by_name(anim);
665 _animation_edit();
666 }
667 }
668 }
669 }
670
_animation_resource_edit()671 void AnimationPlayerEditor::_animation_resource_edit() {
672
673 if (animation->get_item_count()) {
674 String current = animation->get_item_text(animation->get_selected());
675 Ref<Animation> anim = player->get_animation(current);
676 editor->edit_resource(anim);
677 }
678 }
679
_animation_edit()680 void AnimationPlayerEditor::_animation_edit() {
681
682 if (animation->get_item_count()) {
683 String current = animation->get_item_text(animation->get_selected());
684 Ref<Animation> anim = player->get_animation(current);
685 key_editor->set_animation(anim);
686 Node *root = player->get_node(player->get_root());
687 if (root) {
688 key_editor->set_root(root);
689 }
690
691 } else {
692
693 key_editor->set_animation(Ref<Animation>());
694 key_editor->set_root(NULL);
695 }
696 }
_dialog_action(String p_file)697 void AnimationPlayerEditor::_dialog_action(String p_file) {
698
699 switch (current_option) {
700 case RESOURCE_LOAD: {
701 ERR_FAIL_COND(!player);
702
703 Ref<Resource> res = ResourceLoader::load(p_file, "Animation");
704 ERR_FAIL_COND(res.is_null());
705 ERR_FAIL_COND(!res->is_type("Animation"));
706 if (p_file.find_last("/") != -1) {
707
708 p_file = p_file.substr(p_file.find_last("/") + 1, p_file.length());
709 }
710 if (p_file.find_last("\\") != -1) {
711
712 p_file = p_file.substr(p_file.find_last("\\") + 1, p_file.length());
713 }
714
715 if (p_file.find(".") != -1)
716 p_file = p_file.substr(0, p_file.find("."));
717
718 undo_redo->create_action(TTR("Load Animation"));
719 undo_redo->add_do_method(player, "add_animation", p_file, res);
720 undo_redo->add_undo_method(player, "remove_animation", p_file);
721 if (player->has_animation(p_file)) {
722 undo_redo->add_undo_method(player, "add_animation", p_file, player->get_animation(p_file));
723 }
724 undo_redo->add_do_method(this, "_animation_player_changed", player);
725 undo_redo->add_undo_method(this, "_animation_player_changed", player);
726 undo_redo->commit_action();
727 break;
728 }
729 case RESOURCE_SAVE: {
730
731 String current = animation->get_item_text(animation->get_selected());
732 if (current != "") {
733 Ref<Animation> anim = player->get_animation(current);
734
735 ERR_FAIL_COND(!anim->cast_to<Resource>())
736
737 RES current_res = RES(anim->cast_to<Resource>());
738
739 _animation_save_in_path(current_res, p_file);
740 }
741 }
742 }
743 }
744
_scale_changed(const String & p_scale)745 void AnimationPlayerEditor::_scale_changed(const String &p_scale) {
746
747 player->set_speed(p_scale.to_double());
748 }
749
_update_animation()750 void AnimationPlayerEditor::_update_animation() {
751
752 // the purpose of _update_animation is to reflect the current state
753 // of the animation player in the current editor..
754
755 updating = true;
756
757 if (player->is_playing()) {
758
759 play->set_pressed(true);
760 stop->set_pressed(false);
761
762 } else {
763
764 play->set_pressed(false);
765 stop->set_pressed(true);
766 }
767
768 scale->set_text(String::num(player->get_speed(), 2));
769 String current = player->get_current_animation();
770
771 for (int i = 0; i < animation->get_item_count(); i++) {
772
773 if (animation->get_item_text(i) == current) {
774 animation->select(i);
775 break;
776 }
777 }
778
779 updating = false;
780 }
781
_update_player()782 void AnimationPlayerEditor::_update_player() {
783
784 updating = true;
785 List<StringName> animlist;
786 if (player)
787 player->get_animation_list(&animlist);
788
789 animation->clear();
790 if (player)
791 nodename->set_text(player->get_name());
792 else
793 nodename->set_text("<empty>");
794
795 add_anim->set_disabled(player == NULL);
796 load_anim->set_disabled(player == NULL);
797 stop->set_disabled(animlist.size() == 0);
798 play->set_disabled(animlist.size() == 0);
799 play_bw->set_disabled(animlist.size() == 0);
800 play_bw_from->set_disabled(animlist.size() == 0);
801 play_from->set_disabled(animlist.size() == 0);
802 autoplay->set_disabled(animlist.size() == 0);
803 duplicate_anim->set_disabled(animlist.size() == 0);
804 rename_anim->set_disabled(animlist.size() == 0);
805 blend_anim->set_disabled(animlist.size() == 0);
806 remove_anim->set_disabled(animlist.size() == 0);
807 resource_edit_anim->set_disabled(animlist.size() == 0);
808 save_anim->set_disabled(animlist.size() == 0);
809 tool_anim->set_disabled(player == NULL);
810
811 int active_idx = -1;
812 for (List<StringName>::Element *E = animlist.front(); E; E = E->next()) {
813
814 if (player->get_autoplay() == E->get())
815 animation->add_icon_item(autoplay_icon, E->get());
816 else
817 animation->add_item(E->get());
818
819 if (player->get_current_animation() == E->get())
820 active_idx = animation->get_item_count() - 1;
821 }
822
823 if (!player)
824 return;
825
826 updating = false;
827 if (active_idx != -1) {
828 animation->select(active_idx);
829 autoplay->set_pressed(animation->get_item_text(active_idx) == player->get_autoplay());
830 _animation_selected(active_idx);
831
832 } else if (animation->get_item_count() > 0) {
833
834 animation->select(0);
835 autoplay->set_pressed(animation->get_item_text(0) == player->get_autoplay());
836 _animation_selected(0);
837 }
838
839 //pause->set_pressed(player->is_paused());
840
841 if (animation->get_item_count()) {
842 String current = animation->get_item_text(animation->get_selected());
843 Ref<Animation> anim = player->get_animation(current);
844 key_editor->set_animation(anim);
845 Node *root = player->get_node(player->get_root());
846 if (root) {
847 key_editor->set_root(root);
848 }
849 }
850
851 _update_animation();
852 }
853
edit(AnimationPlayer * p_player)854 void AnimationPlayerEditor::edit(AnimationPlayer *p_player) {
855
856 if (player && pin->is_pressed())
857 return; //ignore, pinned
858 player = p_player;
859
860 if (player) {
861 _update_player();
862 key_editor->show_select_node_warning(false);
863 } else {
864 key_editor->show_select_node_warning(true);
865
866 // hide();
867 }
868 }
869
_animation_duplicate()870 void AnimationPlayerEditor::_animation_duplicate() {
871
872 if (!animation->get_item_count())
873 return;
874
875 String current = animation->get_item_text(animation->get_selected());
876 Ref<Animation> anim = player->get_animation(current);
877 if (!anim.is_valid())
878 return;
879
880 Ref<Animation> new_anim = memnew(Animation);
881 List<PropertyInfo> plist;
882 anim->get_property_list(&plist);
883 for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
884
885 if (E->get().usage & PROPERTY_USAGE_STORAGE) {
886
887 new_anim->set(E->get().name, anim->get(E->get().name));
888 }
889 }
890 new_anim->set_path("");
891
892 String new_name = current;
893 while (player->has_animation(new_name)) {
894
895 new_name = new_name + " (copy)";
896 }
897
898 undo_redo->create_action(TTR("Duplicate Animation"));
899 undo_redo->add_do_method(player, "add_animation", new_name, new_anim);
900 undo_redo->add_undo_method(player, "remove_animation", new_name);
901 undo_redo->add_do_method(player, "animation_set_next", new_name, player->animation_get_next(current));
902 undo_redo->add_do_method(this, "_animation_player_changed", player);
903 undo_redo->add_undo_method(this, "_animation_player_changed", player);
904 undo_redo->commit_action();
905
906 for (int i = 0; i < animation->get_item_count(); i++) {
907
908 if (animation->get_item_text(i) == new_name) {
909
910 animation->select(i);
911 _animation_selected(i);
912 return;
913 }
914 }
915 }
916
_seek_value_changed(float p_value,bool p_set)917 void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set) {
918
919 if (updating || !player || player->is_playing()) {
920 return;
921 };
922
923 updating = true;
924 String current = player->get_current_animation(); //animation->get_item_text( animation->get_selected() );
925 if (current == "" || !player->has_animation(current)) {
926 updating = false;
927 current = "";
928 return;
929 };
930
931 Ref<Animation> anim;
932 anim = player->get_animation(current);
933
934 float pos = anim->get_length() * (p_value / frame->get_max());
935 float step = anim->get_step();
936 if (step) {
937 pos = Math::stepify(pos, step);
938 if (pos < 0)
939 pos = 0;
940 if (pos >= anim->get_length())
941 pos = anim->get_length();
942 }
943
944 if (player->is_valid() && !p_set) {
945 float cpos = player->get_current_animation_pos();
946
947 player->seek_delta(pos, pos - cpos);
948 } else {
949 player->seek(pos, true);
950 }
951
952 key_editor->set_anim_pos(pos);
953
954 updating = true;
955 };
956
_animation_player_changed(Object * p_pl)957 void AnimationPlayerEditor::_animation_player_changed(Object *p_pl) {
958
959 if (player == p_pl && is_visible()) {
960
961 _update_player();
962 if (blend_editor.dialog->is_visible())
963 _animation_blend(); //update
964 }
965 }
966
_list_changed()967 void AnimationPlayerEditor::_list_changed() {
968
969 if (is_visible())
970 _update_player();
971 }
972 #if 0
973 void AnimationPlayerEditor::_editor_store() {
974
975 if (animation->get_item_count()==0)
976 return;
977 String current = animation->get_item_text(animation->get_selected());
978 Ref<Animation> anim = player->get_animation(current);
979
980 if (key_editor->get_current_animation()==anim)
981 return; //already there
982
983
984 undo_redo->create_action("Store anim in editor");
985 undo_redo->add_do_method(key_editor,"set_animation",anim);
986 undo_redo->add_undo_method(key_editor,"remove_animation",anim);
987 undo_redo->commit_action();
988 }
989
990 void AnimationPlayerEditor::_editor_load(){
991
992 Ref<Animation> anim = key_editor->get_current_animation();
993 if (anim.is_null())
994 return;
995
996 String existing = player->find_animation(anim);
997 if (existing!="") {
998 _select_anim_by_name(existing);
999 return; //already has
1000 }
1001
1002 int count=1;
1003 String base=anim->get_name();
1004 bool noname=false;
1005 if (base=="") {
1006 base="New Anim";
1007 noname=true;
1008 }
1009
1010 while(true) {
1011 String attempt = base;
1012 if (count>1)
1013 attempt+=" ("+itos(count)+")";
1014 if (player->has_animation(attempt)) {
1015 count++;
1016 continue;
1017 }
1018 base=attempt;
1019 break;
1020 }
1021
1022 if (noname)
1023 anim->set_name(base);
1024
1025 undo_redo->create_action("Add Animation From Editor");
1026 undo_redo->add_do_method(player,"add_animation",base,anim);
1027 undo_redo->add_undo_method(player,"remove_animation",base);
1028 undo_redo->add_do_method(this,"_animation_player_changed",player);
1029 undo_redo->add_undo_method(this,"_animation_player_changed",player);
1030 undo_redo->commit_action();
1031
1032 _select_anim_by_name(base);
1033
1034
1035 }
1036 #endif
1037
_animation_key_editor_anim_len_changed(float p_len)1038 void AnimationPlayerEditor::_animation_key_editor_anim_len_changed(float p_len) {
1039
1040 frame->set_max(p_len);
1041 }
1042
_animation_key_editor_anim_step_changed(float p_len)1043 void AnimationPlayerEditor::_animation_key_editor_anim_step_changed(float p_len) {
1044
1045 if (p_len)
1046 frame->set_step(p_len);
1047 else
1048 frame->set_step(0.00001);
1049 }
1050
_animation_key_editor_seek(float p_pos,bool p_drag)1051 void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag) {
1052
1053 if (!is_visible())
1054 return;
1055 if (!player)
1056 return;
1057
1058 if (player->is_playing())
1059 return;
1060
1061 updating = true;
1062 frame->set_val(p_pos);
1063 updating = false;
1064 _seek_value_changed(p_pos, !p_drag);
1065
1066 EditorNode::get_singleton()->get_property_editor()->refresh();
1067
1068 //seekit
1069 }
1070
_hide_anim_editors()1071 void AnimationPlayerEditor::_hide_anim_editors() {
1072
1073 player = NULL;
1074 hide();
1075 set_process(false);
1076
1077 key_editor->set_animation(Ref<Animation>());
1078 key_editor->set_root(NULL);
1079 key_editor->show_select_node_warning(true);
1080 // editor->animation_editor_make_visible(false);
1081 }
1082
_animation_tool_menu(int p_option)1083 void AnimationPlayerEditor::_animation_tool_menu(int p_option) {
1084
1085 switch (p_option) {
1086
1087 case TOOL_COPY_ANIM: {
1088
1089 if (!animation->get_item_count()) {
1090 error_dialog->set_text(TTR("ERROR: No animation to copy!"));
1091 error_dialog->popup_centered_minsize();
1092 return;
1093 }
1094
1095 String current = animation->get_item_text(animation->get_selected());
1096 Ref<Animation> anim = player->get_animation(current);
1097 //editor->edit_resource(anim);
1098 EditorSettings::get_singleton()->set_resource_clipboard(anim);
1099
1100 } break;
1101 case TOOL_PASTE_ANIM: {
1102
1103 Ref<Animation> anim = EditorSettings::get_singleton()->get_resource_clipboard();
1104 if (!anim.is_valid()) {
1105 error_dialog->set_text(TTR("ERROR: No animation resource on clipboard!"));
1106 error_dialog->popup_centered_minsize();
1107 return;
1108 }
1109
1110 String name = anim->get_name();
1111 if (name == "") {
1112 name = TTR("Pasted Animation");
1113 }
1114
1115 int idx = 1;
1116 String base = name;
1117 while (player->has_animation(name)) {
1118
1119 idx++;
1120 name = base + " " + itos(idx);
1121 }
1122
1123 undo_redo->create_action(TTR("Paste Animation"));
1124 undo_redo->add_do_method(player, "add_animation", name, anim);
1125 undo_redo->add_undo_method(player, "remove_animation", name);
1126 undo_redo->add_do_method(this, "_animation_player_changed", player);
1127 undo_redo->add_undo_method(this, "_animation_player_changed", player);
1128 undo_redo->commit_action();
1129
1130 _select_anim_by_name(name);
1131
1132 } break;
1133 case TOOL_EDIT_RESOURCE: {
1134
1135 if (!animation->get_item_count()) {
1136 error_dialog->set_text(TTR("ERROR: No animation to edit!"));
1137 error_dialog->popup_centered_minsize();
1138 return;
1139 }
1140
1141 String current = animation->get_item_text(animation->get_selected());
1142 Ref<Animation> anim = player->get_animation(current);
1143 editor->edit_resource(anim);
1144
1145 } break;
1146 }
1147 }
1148
_animation_save_menu(int p_option)1149 void AnimationPlayerEditor::_animation_save_menu(int p_option) {
1150
1151 String current = animation->get_item_text(animation->get_selected());
1152 if (current != "") {
1153 Ref<Animation> anim = player->get_animation(current);
1154
1155 switch (p_option) {
1156 case ANIM_SAVE:
1157 _animation_save(anim);
1158 break;
1159 case ANIM_SAVE_AS:
1160 _animation_save_as(anim);
1161 break;
1162 }
1163 }
1164 }
1165
_unhandled_key_input(const InputEvent & p_ev)1166 void AnimationPlayerEditor::_unhandled_key_input(const InputEvent &p_ev) {
1167
1168 if (is_visible() && p_ev.type == InputEvent::KEY && p_ev.key.pressed && !p_ev.key.echo && !p_ev.key.mod.alt && !p_ev.key.mod.control && !p_ev.key.mod.meta) {
1169
1170 switch (p_ev.key.scancode) {
1171
1172 case KEY_A: {
1173 if (!p_ev.key.mod.shift)
1174 _play_bw_from_pressed();
1175 else
1176 _play_bw_pressed();
1177 } break;
1178 case KEY_S: {
1179 _stop_pressed();
1180 } break;
1181 case KEY_D: {
1182 if (!p_ev.key.mod.shift)
1183 _play_from_pressed();
1184 else
1185 _play_pressed();
1186 } break;
1187 }
1188 }
1189 }
1190
_bind_methods()1191 void AnimationPlayerEditor::_bind_methods() {
1192
1193 ObjectTypeDB::bind_method(_MD("_input_event"), &AnimationPlayerEditor::_input_event);
1194 ObjectTypeDB::bind_method(_MD("_node_removed"), &AnimationPlayerEditor::_node_removed);
1195 ObjectTypeDB::bind_method(_MD("_play_pressed"), &AnimationPlayerEditor::_play_pressed);
1196 ObjectTypeDB::bind_method(_MD("_play_from_pressed"), &AnimationPlayerEditor::_play_from_pressed);
1197 ObjectTypeDB::bind_method(_MD("_play_bw_pressed"), &AnimationPlayerEditor::_play_bw_pressed);
1198 ObjectTypeDB::bind_method(_MD("_play_bw_from_pressed"), &AnimationPlayerEditor::_play_bw_from_pressed);
1199 ObjectTypeDB::bind_method(_MD("_stop_pressed"), &AnimationPlayerEditor::_stop_pressed);
1200 ObjectTypeDB::bind_method(_MD("_autoplay_pressed"), &AnimationPlayerEditor::_autoplay_pressed);
1201 ObjectTypeDB::bind_method(_MD("_pause_pressed"), &AnimationPlayerEditor::_pause_pressed);
1202 ObjectTypeDB::bind_method(_MD("_animation_selected"), &AnimationPlayerEditor::_animation_selected);
1203 ObjectTypeDB::bind_method(_MD("_animation_name_edited"), &AnimationPlayerEditor::_animation_name_edited);
1204 ObjectTypeDB::bind_method(_MD("_animation_new"), &AnimationPlayerEditor::_animation_new);
1205 ObjectTypeDB::bind_method(_MD("_animation_rename"), &AnimationPlayerEditor::_animation_rename);
1206 ObjectTypeDB::bind_method(_MD("_animation_load"), &AnimationPlayerEditor::_animation_load);
1207 ObjectTypeDB::bind_method(_MD("_animation_remove"), &AnimationPlayerEditor::_animation_remove);
1208 ObjectTypeDB::bind_method(_MD("_animation_remove_confirmed"), &AnimationPlayerEditor::_animation_remove_confirmed);
1209 ObjectTypeDB::bind_method(_MD("_animation_blend"), &AnimationPlayerEditor::_animation_blend);
1210 ObjectTypeDB::bind_method(_MD("_animation_edit"), &AnimationPlayerEditor::_animation_edit);
1211 ObjectTypeDB::bind_method(_MD("_animation_resource_edit"), &AnimationPlayerEditor::_animation_resource_edit);
1212 ObjectTypeDB::bind_method(_MD("_dialog_action"), &AnimationPlayerEditor::_dialog_action);
1213 ObjectTypeDB::bind_method(_MD("_seek_value_changed"), &AnimationPlayerEditor::_seek_value_changed, DEFVAL(true));
1214 ObjectTypeDB::bind_method(_MD("_animation_player_changed"), &AnimationPlayerEditor::_animation_player_changed);
1215 ObjectTypeDB::bind_method(_MD("_blend_edited"), &AnimationPlayerEditor::_blend_edited);
1216 // ObjectTypeDB::bind_method(_MD("_seek_frame_changed"),&AnimationPlayerEditor::_seek_frame_changed);
1217 ObjectTypeDB::bind_method(_MD("_scale_changed"), &AnimationPlayerEditor::_scale_changed);
1218 //ObjectTypeDB::bind_method(_MD("_editor_store_all"),&AnimationPlayerEditor::_editor_store_all);
1219 ///jectTypeDB::bind_method(_MD("_editor_load_all"),&AnimationPlayerEditor::_editor_load_all);
1220 ObjectTypeDB::bind_method(_MD("_list_changed"), &AnimationPlayerEditor::_list_changed);
1221 ObjectTypeDB::bind_method(_MD("_animation_key_editor_seek"), &AnimationPlayerEditor::_animation_key_editor_seek);
1222 ObjectTypeDB::bind_method(_MD("_animation_key_editor_anim_len_changed"), &AnimationPlayerEditor::_animation_key_editor_anim_len_changed);
1223 ObjectTypeDB::bind_method(_MD("_animation_key_editor_anim_step_changed"), &AnimationPlayerEditor::_animation_key_editor_anim_step_changed);
1224 ObjectTypeDB::bind_method(_MD("_hide_anim_editors"), &AnimationPlayerEditor::_hide_anim_editors);
1225 ObjectTypeDB::bind_method(_MD("_animation_duplicate"), &AnimationPlayerEditor::_animation_duplicate);
1226 ObjectTypeDB::bind_method(_MD("_blend_editor_next_changed"), &AnimationPlayerEditor::_blend_editor_next_changed);
1227 ObjectTypeDB::bind_method(_MD("_unhandled_key_input"), &AnimationPlayerEditor::_unhandled_key_input);
1228 ObjectTypeDB::bind_method(_MD("_animation_tool_menu"), &AnimationPlayerEditor::_animation_tool_menu);
1229 ObjectTypeDB::bind_method(_MD("_animation_save_menu"), &AnimationPlayerEditor::_animation_save_menu);
1230 }
1231
1232 AnimationPlayerEditor *AnimationPlayerEditor::singleton = NULL;
1233
get_player() const1234 AnimationPlayer *AnimationPlayerEditor::get_player() const {
1235
1236 return player;
1237 }
AnimationPlayerEditor(EditorNode * p_editor)1238 AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) {
1239 editor = p_editor;
1240 singleton = this;
1241
1242 updating = false;
1243
1244 set_focus_mode(FOCUS_ALL);
1245
1246 player = NULL;
1247 add_style_override("panel", get_stylebox("panel", "Panel"));
1248
1249 Label *l;
1250
1251 /*l= memnew( Label );
1252 l->set_text("Animation Player:");
1253 add_child(l);*/
1254
1255 HBoxContainer *hb = memnew(HBoxContainer);
1256 add_child(hb);
1257
1258 play_bw_from = memnew(ToolButton);
1259 play_bw_from->set_tooltip(TTR("Play selected animation backwards from current pos. (A)"));
1260 hb->add_child(play_bw_from);
1261
1262 play_bw = memnew(ToolButton);
1263 play_bw->set_tooltip(TTR("Play selected animation backwards from end. (Shift+A)"));
1264 hb->add_child(play_bw);
1265
1266 stop = memnew(ToolButton);
1267 stop->set_toggle_mode(true);
1268 hb->add_child(stop);
1269 stop->set_tooltip(TTR("Stop animation playback. (S)"));
1270
1271 play = memnew(ToolButton);
1272 play->set_tooltip(TTR("Play selected animation from start. (Shift+D)"));
1273 hb->add_child(play);
1274
1275 play_from = memnew(ToolButton);
1276 play_from->set_tooltip(TTR("Play selected animation from current pos. (D)"));
1277 hb->add_child(play_from);
1278
1279 //pause = memnew( Button );
1280 //pause->set_toggle_mode(true);
1281 //hb->add_child(pause);
1282
1283 frame = memnew(SpinBox);
1284 hb->add_child(frame);
1285 frame->set_custom_minimum_size(Size2(60, 0));
1286 frame->set_stretch_ratio(2);
1287 frame->set_tooltip(TTR("Animation position (in seconds)."));
1288
1289 hb->add_child(memnew(VSeparator));
1290
1291 scale = memnew(LineEdit);
1292 hb->add_child(scale);
1293 scale->set_h_size_flags(SIZE_EXPAND_FILL);
1294 scale->set_stretch_ratio(1);
1295 scale->set_tooltip(TTR("Scale animation playback globally for the node."));
1296 scale->hide();
1297
1298 add_anim = memnew(ToolButton);
1299 ED_SHORTCUT("animation_player_editor/add_animation", TTR("Create new animation in player."));
1300 add_anim->set_shortcut(ED_GET_SHORTCUT("animation_player_editor/add_animation"));
1301 add_anim->set_tooltip(TTR("Create new animation in player."));
1302
1303 hb->add_child(add_anim);
1304
1305 load_anim = memnew(ToolButton);
1306 ED_SHORTCUT("animation_player_editor/load_from_disk", TTR("Load animation from disk."));
1307 add_anim->set_shortcut(ED_GET_SHORTCUT("animation_player_editor/load_from_disk"));
1308 load_anim->set_tooltip(TTR("Load an animation from disk."));
1309 hb->add_child(load_anim);
1310
1311 save_anim = memnew(MenuButton);
1312 save_anim->set_tooltip(TTR("Save the current animation"));
1313 save_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/save", TTR("Save")), ANIM_SAVE);
1314 save_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/save_as", TTR("Save As")), ANIM_SAVE_AS);
1315 save_anim->set_focus_mode(Control::FOCUS_NONE);
1316 hb->add_child(save_anim);
1317
1318 accept = memnew(AcceptDialog);
1319 add_child(accept);
1320 accept->connect("confirmed", this, "_menu_confirm_current");
1321
1322 delete_dialog = memnew(ConfirmationDialog);
1323 add_child(delete_dialog);
1324 delete_dialog->connect("confirmed", this, "_animation_remove_confirmed");
1325
1326 duplicate_anim = memnew(ToolButton);
1327 hb->add_child(duplicate_anim);
1328 ED_SHORTCUT("animation_player_editor/duplicate_animation", TTR("Duplicate Animation"));
1329 duplicate_anim->set_shortcut(ED_GET_SHORTCUT("animation_player_editor/duplicate_animation"));
1330 duplicate_anim->set_tooltip(TTR("Duplicate Animation"));
1331
1332 rename_anim = memnew(ToolButton);
1333 hb->add_child(rename_anim);
1334 ED_SHORTCUT("animation_player_editor/rename_animation", TTR("Rename Animation"));
1335 rename_anim->set_shortcut(ED_GET_SHORTCUT("animation_player_editor/rename_animation"));
1336 rename_anim->set_tooltip(TTR("Rename Animation"));
1337
1338 remove_anim = memnew(ToolButton);
1339 hb->add_child(remove_anim);
1340 ED_SHORTCUT("animation_player_editor/remove_animation", TTR("Remove Animation"));
1341 remove_anim->set_shortcut(ED_GET_SHORTCUT("animation_player_editor/remove_animation"));
1342 remove_anim->set_tooltip(TTR("Remove Animation"));
1343
1344 animation = memnew(OptionButton);
1345 hb->add_child(animation);
1346 animation->set_h_size_flags(SIZE_EXPAND_FILL);
1347 animation->set_tooltip(TTR("Display list of animations in player."));
1348 animation->set_clip_text(true);
1349
1350 autoplay = memnew(ToolButton);
1351 hb->add_child(autoplay);
1352 autoplay->set_tooltip(TTR("Autoplay on Load"));
1353
1354 blend_anim = memnew(ToolButton);
1355 hb->add_child(blend_anim);
1356 blend_anim->set_tooltip(TTR("Edit Target Blend Times"));
1357
1358 tool_anim = memnew(MenuButton);
1359 //tool_anim->set_flat(false);
1360 tool_anim->set_tooltip(TTR("Animation Tools"));
1361 tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/copy_animation", TTR("Copy Animation")), TOOL_COPY_ANIM);
1362 tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/paste_animation", TTR("Paste Animation")), TOOL_PASTE_ANIM);
1363 //tool_anim->get_popup()->add_separator();
1364 //tool_anim->get_popup()->add_item("Edit Anim Resource",TOOL_PASTE_ANIM);
1365 hb->add_child(tool_anim);
1366
1367 nodename = memnew(Button);
1368 hb->add_child(nodename);
1369 pin = memnew(ToolButton);
1370 pin->set_toggle_mode(true);
1371 hb->add_child(pin);
1372
1373 resource_edit_anim = memnew(Button);
1374 hb->add_child(resource_edit_anim);
1375 resource_edit_anim->hide();
1376
1377 file = memnew(EditorFileDialog);
1378 add_child(file);
1379
1380 name_dialog = memnew(ConfirmationDialog);
1381 name_dialog->set_title(TTR("Create New Animation"));
1382 name_dialog->set_hide_on_ok(false);
1383 add_child(name_dialog);
1384 name = memnew(LineEdit);
1385 name_dialog->add_child(name);
1386 name->set_pos(Point2(18, 30));
1387 name->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 10);
1388 name_dialog->register_text_enter(name);
1389
1390 l = memnew(Label);
1391 l->set_text(TTR("Animation Name:"));
1392 l->set_pos(Point2(10, 10));
1393
1394 name_dialog->add_child(l);
1395 name_title = l;
1396
1397 error_dialog = memnew(ConfirmationDialog);
1398 error_dialog->get_ok()->set_text(TTR("Close"));
1399 //error_dialog->get_cancel()->set_text("Close");
1400 error_dialog->set_text(TTR("Error!"));
1401 add_child(error_dialog);
1402
1403 name_dialog->connect("confirmed", this, "_animation_name_edited");
1404
1405 blend_editor.dialog = memnew(AcceptDialog);
1406 add_child(blend_editor.dialog);
1407 blend_editor.dialog->get_ok()->set_text(TTR("Close"));
1408 blend_editor.dialog->set_hide_on_ok(true);
1409 VBoxContainer *blend_vb = memnew(VBoxContainer);
1410 blend_editor.dialog->add_child(blend_vb);
1411 blend_editor.dialog->set_child_rect(blend_vb);
1412 blend_editor.tree = memnew(Tree);
1413 blend_editor.tree->set_columns(2);
1414 blend_vb->add_margin_child(TTR("Blend Times:"), blend_editor.tree, true);
1415 blend_editor.next = memnew(OptionButton);
1416 blend_vb->add_margin_child(TTR("Next (Auto Queue):"), blend_editor.next);
1417 blend_editor.dialog->set_title(TTR("Cross-Animation Blend Times"));
1418 updating_blends = false;
1419
1420 blend_editor.tree->connect("item_edited", this, "_blend_edited");
1421
1422 autoplay->connect("pressed", this, "_autoplay_pressed");
1423 autoplay->set_toggle_mode(true);
1424 play->connect("pressed", this, "_play_pressed");
1425 play_from->connect("pressed", this, "_play_from_pressed");
1426 play_bw->connect("pressed", this, "_play_bw_pressed");
1427 play_bw_from->connect("pressed", this, "_play_bw_from_pressed");
1428 stop->connect("pressed", this, "_stop_pressed");
1429 //pause->connect("pressed", this,"_pause_pressed");
1430 add_anim->connect("pressed", this, "_animation_new");
1431 rename_anim->connect("pressed", this, "_animation_rename");
1432 load_anim->connect("pressed", this, "_animation_load");
1433 duplicate_anim->connect("pressed", this, "_animation_duplicate");
1434 //frame->connect("text_entered", this,"_seek_frame_changed");
1435
1436 blend_anim->connect("pressed", this, "_animation_blend");
1437 remove_anim->connect("pressed", this, "_animation_remove");
1438 animation->connect("item_selected", this, "_animation_selected", Vector<Variant>(), true);
1439 resource_edit_anim->connect("pressed", this, "_animation_resource_edit");
1440 file->connect("file_selected", this, "_dialog_action");
1441 frame->connect("value_changed", this, "_seek_value_changed", Vector<Variant>(), true);
1442 scale->connect("text_entered", this, "_scale_changed", Vector<Variant>(), true);
1443
1444 renaming = false;
1445 last_active = false;
1446
1447 set_process_unhandled_key_input(true);
1448
1449 key_editor = memnew(AnimationKeyEditor);
1450 add_child(key_editor);
1451 add_constant_override("separation", get_constant("separation", "VBoxContainer"));
1452 key_editor->set_v_size_flags(SIZE_EXPAND_FILL);
1453 key_editor->connect("timeline_changed", this, "_animation_key_editor_seek");
1454 key_editor->connect("animation_len_changed", this, "_animation_key_editor_anim_len_changed");
1455 key_editor->connect("animation_step_changed", this, "_animation_key_editor_anim_step_changed");
1456
1457 _update_player();
1458 }
1459
edit(Object * p_object)1460 void AnimationPlayerEditorPlugin::edit(Object *p_object) {
1461
1462 anim_editor->set_undo_redo(&get_undo_redo());
1463 if (!p_object)
1464 return;
1465 anim_editor->edit(p_object->cast_to<AnimationPlayer>());
1466 }
1467
handles(Object * p_object) const1468 bool AnimationPlayerEditorPlugin::handles(Object *p_object) const {
1469
1470 return p_object->is_type("AnimationPlayer");
1471 }
1472
make_visible(bool p_visible)1473 void AnimationPlayerEditorPlugin::make_visible(bool p_visible) {
1474
1475 if (p_visible) {
1476
1477 editor->make_bottom_panel_item_visible(anim_editor);
1478 anim_editor->set_process(true);
1479 anim_editor->ensure_visibility();
1480 // editor->animation_panel_make_visible(true);
1481 } else {
1482
1483 // anim_editor->hide();
1484 // anim_editor->set_idle_process(false);
1485 }
1486 }
1487
AnimationPlayerEditorPlugin(EditorNode * p_node)1488 AnimationPlayerEditorPlugin::AnimationPlayerEditorPlugin(EditorNode *p_node) {
1489
1490 editor = p_node;
1491 anim_editor = memnew(AnimationPlayerEditor(editor));
1492 anim_editor->set_undo_redo(editor->get_undo_redo());
1493
1494 editor->add_bottom_panel_item(TTR("Animation"), anim_editor);
1495 /*
1496 editor->get_viewport()->add_child(anim_editor);
1497 anim_editor->set_area_as_parent_rect();
1498 anim_editor->set_anchor( MARGIN_TOP, Control::ANCHOR_END);
1499 anim_editor->set_margin( MARGIN_TOP, 75 );
1500 anim_editor->set_anchor( MARGIN_RIGHT, Control::ANCHOR_END);
1501 anim_editor->set_margin( MARGIN_RIGHT, 0 );*/
1502 anim_editor->hide();
1503 }
1504
~AnimationPlayerEditorPlugin()1505 AnimationPlayerEditorPlugin::~AnimationPlayerEditorPlugin() {
1506 }
1507