| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  animation_player_editor_plugin.cpp                                   */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2021-01-01 20:13:46 +01:00
										 |  |  | /* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include "animation_player_editor_plugin.h"
 | 
					
						
							| 
									
										
										
										
											2017-01-16 08:04:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/io/resource_loader.h"
 | 
					
						
							|  |  |  | #include "core/io/resource_saver.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-06 01:15:20 +02:00
										 |  |  | #include "core/os/input.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/os/keyboard.h"
 | 
					
						
							|  |  |  | #include "core/project_settings.h"
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | #include "editor/animation_track_editor.h"
 | 
					
						
							| 
									
										
										
										
											2019-12-24 15:17:23 +08:00
										 |  |  | #include "editor/editor_scale.h"
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | #include "editor/editor_settings.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-04 02:20:57 -03:00
										 |  |  | // For onion skinning.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | #include "editor/plugins/canvas_item_editor_plugin.h"
 | 
					
						
							|  |  |  | #include "editor/plugins/spatial_editor_plugin.h"
 | 
					
						
							|  |  |  | #include "scene/main/viewport.h"
 | 
					
						
							|  |  |  | #include "servers/visual_server.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void AnimationPlayerEditor::_node_removed(Node *p_node) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (player && player == p_node) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		player = NULL; | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		set_process(false); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 		track_editor->set_animation(Ref<Animation>()); | 
					
						
							|  |  |  | 		track_editor->set_root(NULL); | 
					
						
							|  |  |  | 		track_editor->show_select_node_warning(true); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 		_update_player(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_notification(int p_what) { | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 04:19:43 +02:00
										 |  |  | 	switch (p_what) { | 
					
						
							|  |  |  | 		case NOTIFICATION_PROCESS: { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 04:19:43 +02:00
										 |  |  | 			if (!player) | 
					
						
							|  |  |  | 				return; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 04:19:43 +02:00
										 |  |  | 			updating = true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 04:19:43 +02:00
										 |  |  | 			if (player->is_playing()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 04:19:43 +02:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2018-01-14 12:28:57 +02:00
										 |  |  | 					String animname = player->get_assigned_animation(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 04:19:43 +02:00
										 |  |  | 					if (player->has_animation(animname)) { | 
					
						
							|  |  |  | 						Ref<Animation> anim = player->get_animation(animname); | 
					
						
							|  |  |  | 						if (!anim.is_null()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 04:19:43 +02:00
										 |  |  | 							frame->set_max(anim->get_length()); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-09-10 15:37:49 +02:00
										 |  |  | 				frame->set_value(player->get_current_animation_position()); | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 				track_editor->set_anim_pos(player->get_current_animation_position()); | 
					
						
							| 
									
										
										
										
											2018-05-15 17:12:35 -03:00
										 |  |  | 				EditorNode::get_singleton()->get_inspector()->refresh(); | 
					
						
							| 
									
										
										
										
											2017-09-09 04:19:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-30 17:47:09 +01:00
										 |  |  | 			} else if (!player->is_valid()) { | 
					
						
							|  |  |  | 				// Reset timeline when the player has been stopped externally
 | 
					
						
							|  |  |  | 				frame->set_value(0); | 
					
						
							| 
									
										
										
										
											2017-09-09 04:19:43 +02:00
										 |  |  | 			} else if (last_active) { | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 				// Need the last frame after it stopped.
 | 
					
						
							| 
									
										
										
										
											2017-09-10 15:37:49 +02:00
										 |  |  | 				frame->set_value(player->get_current_animation_position()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-01-03 15:39:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 04:19:43 +02:00
										 |  |  | 			last_active = player->is_playing(); | 
					
						
							|  |  |  | 			updating = false; | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case NOTIFICATION_ENTER_TREE: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			tool_anim->get_popup()->connect("id_pressed", this, "_animation_tool_menu"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 			onion_skinning->get_popup()->connect("id_pressed", this, "_onion_skinning_menu"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 04:19:43 +02:00
										 |  |  | 			blend_editor.next->connect("item_selected", this, "_blend_editor_next_changed"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 04:19:43 +02:00
										 |  |  | 			get_tree()->connect("node_removed", this, "_node_removed"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			add_style_override("panel", editor->get_gui_base()->get_stylebox("panel", "Panel")); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			add_style_override("panel", editor->get_gui_base()->get_stylebox("panel", "Panel")); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case NOTIFICATION_THEME_CHANGED: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			autoplay->set_icon(get_icon("AutoPlay", "EditorIcons")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			play->set_icon(get_icon("PlayStart", "EditorIcons")); | 
					
						
							|  |  |  | 			play_from->set_icon(get_icon("Play", "EditorIcons")); | 
					
						
							|  |  |  | 			play_bw->set_icon(get_icon("PlayStartBackwards", "EditorIcons")); | 
					
						
							|  |  |  | 			play_bw_from->set_icon(get_icon("PlayBackwards", "EditorIcons")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			autoplay_icon = get_icon("AutoPlay", "EditorIcons"); | 
					
						
							|  |  |  | 			stop->set_icon(get_icon("Stop", "EditorIcons")); | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-14 00:42:05 -03:00
										 |  |  | 			onion_toggle->set_icon(get_icon("Onion", "EditorIcons")); | 
					
						
							| 
									
										
										
										
											2020-07-11 12:32:27 -03:00
										 |  |  | 			onion_skinning->set_icon(get_icon("GuiTabMenuHl", "EditorIcons")); | 
					
						
							| 
									
										
										
										
											2019-05-14 00:42:05 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 04:19:43 +02:00
										 |  |  | 			pin->set_icon(get_icon("Pin", "EditorIcons")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 			tool_anim->add_style_override("normal", get_stylebox("normal", "Button")); | 
					
						
							|  |  |  | 			track_editor->get_edit_menu()->add_style_override("normal", get_stylebox("normal", "Button")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define ITEM_ICON(m_item, m_icon) tool_anim->get_popup()->set_item_icon(tool_anim->get_popup()->get_item_index(m_item), get_icon(m_icon, "EditorIcons"))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ITEM_ICON(TOOL_NEW_ANIM, "New"); | 
					
						
							|  |  |  | 			ITEM_ICON(TOOL_LOAD_ANIM, "Load"); | 
					
						
							|  |  |  | 			ITEM_ICON(TOOL_SAVE_ANIM, "Save"); | 
					
						
							|  |  |  | 			ITEM_ICON(TOOL_SAVE_AS_ANIM, "Save"); | 
					
						
							|  |  |  | 			ITEM_ICON(TOOL_DUPLICATE_ANIM, "Duplicate"); | 
					
						
							|  |  |  | 			ITEM_ICON(TOOL_RENAME_ANIM, "Rename"); | 
					
						
							|  |  |  | 			ITEM_ICON(TOOL_EDIT_TRANSITIONS, "Blend"); | 
					
						
							| 
									
										
										
										
											2018-07-01 17:44:15 -03:00
										 |  |  | 			ITEM_ICON(TOOL_EDIT_RESOURCE, "Edit"); | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 			ITEM_ICON(TOOL_REMOVE_ANIM, "Remove"); | 
					
						
							| 
									
										
										
										
											2017-09-09 04:19:43 +02:00
										 |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_autoplay_pressed() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (updating) | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (animation->get_item_count() == 0) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	String current = animation->get_item_text(animation->get_selected()); | 
					
						
							|  |  |  | 	if (player->get_autoplay() == current) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		//unset
 | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 		undo_redo->create_action(TTR("Toggle Autoplay")); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		undo_redo->add_do_method(player, "set_autoplay", ""); | 
					
						
							|  |  |  | 		undo_redo->add_undo_method(player, "set_autoplay", player->get_autoplay()); | 
					
						
							|  |  |  | 		undo_redo->add_do_method(this, "_animation_player_changed", player); | 
					
						
							|  |  |  | 		undo_redo->add_undo_method(this, "_animation_player_changed", player); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		undo_redo->commit_action(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		//set
 | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 		undo_redo->create_action(TTR("Toggle Autoplay")); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		undo_redo->add_do_method(player, "set_autoplay", current); | 
					
						
							|  |  |  | 		undo_redo->add_undo_method(player, "set_autoplay", player->get_autoplay()); | 
					
						
							|  |  |  | 		undo_redo->add_do_method(this, "_animation_player_changed", player); | 
					
						
							|  |  |  | 		undo_redo->add_undo_method(this, "_animation_player_changed", player); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		undo_redo->commit_action(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_play_pressed() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String current; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		current = animation->get_item_text(animation->get_selected()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (current != "") { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 12:28:57 +02:00
										 |  |  | 		if (current == player->get_assigned_animation()) | 
					
						
							| 
									
										
										
										
											2018-01-18 21:37:17 +01:00
										 |  |  | 			player->stop(); //so it won't blend with itself
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		player->play(current); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//unstop
 | 
					
						
							|  |  |  | 	stop->set_pressed(false); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_play_from_pressed() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String current; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) { | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		current = animation->get_item_text(animation->get_selected()); | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (current != "") { | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-10 15:37:49 +02:00
										 |  |  | 		float time = player->get_current_animation_position(); | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 12:28:57 +02:00
										 |  |  | 		if (current == player->get_assigned_animation() && player->is_playing()) { | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 21:37:17 +01:00
										 |  |  | 			player->stop(); //so it won't blend with itself
 | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		player->play(current); | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 		player->seek(time); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//unstop
 | 
					
						
							|  |  |  | 	stop->set_pressed(false); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_play_bw_pressed() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String current; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) { | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		current = animation->get_item_text(animation->get_selected()); | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (current != "") { | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 12:28:57 +02:00
										 |  |  | 		if (current == player->get_assigned_animation()) | 
					
						
							| 
									
										
										
										
											2018-01-18 21:37:17 +01:00
										 |  |  | 			player->stop(); //so it won't blend with itself
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		player->play(current, -1, -1, true); | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//unstop
 | 
					
						
							|  |  |  | 	stop->set_pressed(false); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_play_bw_from_pressed() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String current; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) { | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		current = animation->get_item_text(animation->get_selected()); | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (current != "") { | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-10 15:37:49 +02:00
										 |  |  | 		float time = player->get_current_animation_position(); | 
					
						
							| 
									
										
										
										
											2018-01-14 12:28:57 +02:00
										 |  |  | 		if (current == player->get_assigned_animation()) | 
					
						
							| 
									
										
										
										
											2018-01-18 21:37:17 +01:00
										 |  |  | 			player->stop(); //so it won't blend with itself
 | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		player->play(current, -1, -1, true); | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 		player->seek(time); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//unstop
 | 
					
						
							|  |  |  | 	stop->set_pressed(false); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void AnimationPlayerEditor::_stop_pressed() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-01 17:49:43 +02:00
										 |  |  | 	if (!player) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 	player->stop(false); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	play->set_pressed(false); | 
					
						
							|  |  |  | 	stop->set_pressed(true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-31 04:43:46 +09:00
										 |  |  | void AnimationPlayerEditor::_animation_selected(int p_which) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-31 04:43:46 +09:00
										 |  |  | 	if (updating) | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	// when selecting an animation, the idea is that the only interesting behavior
 | 
					
						
							|  |  |  | 	// ui-wise is that it should play/blend the next one if currently playing
 | 
					
						
							| 
									
										
										
										
											2019-05-31 04:43:46 +09:00
										 |  |  | 	String current; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-31 04:43:46 +09:00
										 |  |  | 		current = animation->get_item_text(animation->get_selected()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-06 21:39:24 +02:00
										 |  |  | 	if (current != "") { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		player->set_assigned_animation(current); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-31 04:43:46 +09:00
										 |  |  | 		Ref<Animation> anim = player->get_animation(current); | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-05-06 21:39:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 			track_editor->set_animation(anim); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			Node *root = player->get_node(player->get_root()); | 
					
						
							|  |  |  | 			if (root) { | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 				track_editor->set_root(root); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 		frame->set_max(anim->get_length()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 		track_editor->set_animation(Ref<Animation>()); | 
					
						
							|  |  |  | 		track_editor->set_root(NULL); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	autoplay->set_pressed(current == player->get_autoplay()); | 
					
						
							| 
									
										
										
										
											2018-07-03 15:57:54 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	AnimationPlayerEditor::singleton->get_track_editor()->update_keying(); | 
					
						
							|  |  |  | 	EditorNode::get_singleton()->update_keying(); | 
					
						
							| 
									
										
										
										
											2019-10-01 18:38:03 +02:00
										 |  |  | 	_animation_key_editor_seek(timeline_position, false); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_animation_new() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	renaming = false; | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 	name_title->set_text(TTR("New Animation Name:")); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	int count = 1; | 
					
						
							|  |  |  | 	String base = TTR("New Anim"); | 
					
						
							|  |  |  | 	while (true) { | 
					
						
							|  |  |  | 		String attempt = base; | 
					
						
							|  |  |  | 		if (count > 1) | 
					
						
							|  |  |  | 			attempt += " (" + itos(count) + ")"; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		if (player->has_animation(attempt)) { | 
					
						
							|  |  |  | 			count++; | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		base = attempt; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	name->set_text(base); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	name_dialog->popup_centered(Size2(300, 90)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	name->select_all(); | 
					
						
							|  |  |  | 	name->grab_focus(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | void AnimationPlayerEditor::_animation_rename() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (animation->get_item_count() == 0) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	int selected = animation->get_selected(); | 
					
						
							|  |  |  | 	String selected_name = animation->get_item_text(selected); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 	name_title->set_text(TTR("Change Animation Name:")); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	name->set_text(selected_name); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	renaming = true; | 
					
						
							|  |  |  | 	name_dialog->popup_centered(Size2(300, 90)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	name->select_all(); | 
					
						
							|  |  |  | 	name->grab_focus(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | void AnimationPlayerEditor::_animation_load() { | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!player); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	file->set_mode(EditorFileDialog::MODE_OPEN_FILE); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	file->clear_filters(); | 
					
						
							|  |  |  | 	List<String> extensions; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ResourceLoader::get_recognized_extensions_for_type("Animation", &extensions); | 
					
						
							|  |  |  | 	for (List<String>::Element *E = extensions.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		file->add_filter("*." + E->get() + " ; " + E->get().to_upper()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	file->popup_centered_ratio(); | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 	current_option = RESOURCE_LOAD; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void AnimationPlayerEditor::_animation_save_in_path(const Ref<Resource> &p_resource, const String &p_path) { | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	int flg = 0; | 
					
						
							| 
									
										
										
										
											2017-01-05 19:41:36 -03:00
										 |  |  | 	if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 		flg |= ResourceSaver::FLAG_COMPRESS; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-19 17:00:46 -03:00
										 |  |  | 	String path = ProjectSettings::get_singleton()->localize_path(p_path); | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 	Error err = ResourceSaver::save(path, p_resource, flg | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (err != OK) { | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 		accept->set_text(TTR("Error saving resource!")); | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 		accept->popup_centered_minsize(); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	((Resource *)p_resource.ptr())->set_path(path); | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 	editor->emit_signal("resource_saved", p_resource); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void AnimationPlayerEditor::_animation_save(const Ref<Resource> &p_resource) { | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (p_resource->get_path().is_resource_file()) { | 
					
						
							|  |  |  | 		_animation_save_in_path(p_resource, p_resource->get_path()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 		_animation_save_as(p_resource); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void AnimationPlayerEditor::_animation_save_as(const Ref<Resource> &p_resource) { | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	file->set_mode(EditorFileDialog::MODE_SAVE_FILE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	List<String> extensions; | 
					
						
							|  |  |  | 	ResourceSaver::get_recognized_extensions(p_resource, &extensions); | 
					
						
							|  |  |  | 	file->clear_filters(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < extensions.size(); i++) { | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper()); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-19 01:22:36 +02:00
										 |  |  | 	String path; | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 	//file->set_current_path(current_path);
 | 
					
						
							|  |  |  | 	if (p_resource->get_path() != "") { | 
					
						
							| 
									
										
										
										
											2020-06-19 01:22:36 +02:00
										 |  |  | 		path = p_resource->get_path(); | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 		if (extensions.size()) { | 
					
						
							| 
									
										
										
										
											2020-06-19 01:22:36 +02:00
										 |  |  | 			if (extensions.find(p_resource->get_path().get_extension().to_lower()) == NULL) { | 
					
						
							|  |  |  | 				path = p_resource->get_path().get_base_dir() + p_resource->get_name() + "." + extensions.front()->get(); | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 		if (extensions.size()) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (p_resource->get_name() != "") { | 
					
						
							| 
									
										
										
										
											2020-06-19 01:22:36 +02:00
										 |  |  | 				path = p_resource->get_name() + "." + extensions.front()->get().to_lower(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2020-06-19 01:22:36 +02:00
										 |  |  | 				path = "new_" + p_resource->get_class().to_lower() + "." + extensions.front()->get().to_lower(); | 
					
						
							| 
									
										
										
										
											2017-01-14 14:45:42 -05:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-06-19 01:22:36 +02:00
										 |  |  | 	file->set_current_path(path); | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 	file->popup_centered_ratio(); | 
					
						
							| 
									
										
										
										
											2018-04-22 19:36:01 +02:00
										 |  |  | 	file->set_title(TTR("Save Resource As...")); | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 	current_option = RESOURCE_SAVE; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-01-25 21:22:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void AnimationPlayerEditor::_animation_remove() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-25 21:22:16 +01:00
										 |  |  | 	if (animation->get_item_count() == 0) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-25 21:22:16 +01:00
										 |  |  | 	delete_dialog->set_text(TTR("Delete Animation?")); | 
					
						
							|  |  |  | 	delete_dialog->popup_centered_minsize(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_animation_remove_confirmed() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-25 21:22:16 +01:00
										 |  |  | 	String current = animation->get_item_text(animation->get_selected()); | 
					
						
							|  |  |  | 	Ref<Animation> anim = player->get_animation(current); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 	undo_redo->create_action(TTR("Remove Animation")); | 
					
						
							| 
									
										
										
										
											2018-04-25 22:09:41 -03:00
										 |  |  | 	if (player->get_autoplay() == current) { | 
					
						
							|  |  |  | 		undo_redo->add_do_method(player, "set_autoplay", ""); | 
					
						
							|  |  |  | 		undo_redo->add_undo_method(player, "set_autoplay", current); | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 		// Avoid having the autoplay icon linger around if there is only one animation in the player.
 | 
					
						
							| 
									
										
										
										
											2018-04-25 22:09:41 -03:00
										 |  |  | 		undo_redo->add_do_method(this, "_animation_player_changed", player); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-25 21:22:16 +01:00
										 |  |  | 	undo_redo->add_do_method(player, "remove_animation", current); | 
					
						
							|  |  |  | 	undo_redo->add_undo_method(player, "add_animation", current, anim); | 
					
						
							|  |  |  | 	undo_redo->add_do_method(this, "_animation_player_changed", player); | 
					
						
							|  |  |  | 	undo_redo->add_undo_method(this, "_animation_player_changed", player); | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	if (animation->get_item_count() == 1) { | 
					
						
							|  |  |  | 		undo_redo->add_do_method(this, "_stop_onion_skinning"); | 
					
						
							|  |  |  | 		undo_redo->add_undo_method(this, "_start_onion_skinning"); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	undo_redo->commit_action(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void AnimationPlayerEditor::_select_anim_by_name(const String &p_anim) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	int idx = -1; | 
					
						
							|  |  |  | 	for (int i = 0; i < animation->get_item_count(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (animation->get_item_text(i) == p_anim) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			idx = i; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_COND(idx == -1); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	animation->select(idx); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_animation_selected(idx); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-02 15:49:55 +02:00
										 |  |  | double AnimationPlayerEditor::_get_editor_step() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Returns the effective snapping value depending on snapping modifiers, or 0 if snapping is disabled.
 | 
					
						
							|  |  |  | 	if (track_editor->is_snap_enabled()) { | 
					
						
							|  |  |  | 		const String current = player->get_assigned_animation(); | 
					
						
							|  |  |  | 		const Ref<Animation> anim = player->get_animation(current); | 
					
						
							| 
									
										
										
										
											2019-10-03 20:42:22 +02:00
										 |  |  | 		ERR_FAIL_COND_V(!anim.is_valid(), 0.0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-02 15:49:55 +02:00
										 |  |  | 		// Use more precise snapping when holding Shift
 | 
					
						
							|  |  |  | 		return Input::get_singleton()->is_key_pressed(KEY_SHIFT) ? anim->get_step() * 0.25 : anim->get_step(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0.0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void AnimationPlayerEditor::_animation_name_edited() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	player->stop(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String new_name = name->get_text(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (new_name == "" || new_name.find(":") != -1 || new_name.find("/") != -1) { | 
					
						
							| 
									
										
										
										
											2018-04-26 22:58:30 -03:00
										 |  |  | 		error_dialog->set_text(TTR("Invalid animation name!")); | 
					
						
							| 
									
										
										
										
											2015-04-08 14:02:13 -03:00
										 |  |  | 		error_dialog->popup_centered_minsize(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (renaming && animation->get_item_count() > 0 && animation->get_item_text(animation->get_selected()) == new_name) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		name_dialog->hide(); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (player->has_animation(new_name)) { | 
					
						
							| 
									
										
										
										
											2018-04-26 22:58:30 -03:00
										 |  |  | 		error_dialog->set_text(TTR("Animation name already exists!")); | 
					
						
							| 
									
										
										
										
											2015-04-08 14:02:13 -03:00
										 |  |  | 		error_dialog->popup_centered_minsize(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (renaming) { | 
					
						
							|  |  |  | 		String current = animation->get_item_text(animation->get_selected()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		Ref<Animation> anim = player->get_animation(current); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 		undo_redo->create_action(TTR("Rename Animation")); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		undo_redo->add_do_method(player, "rename_animation", current, new_name); | 
					
						
							|  |  |  | 		undo_redo->add_do_method(anim.ptr(), "set_name", new_name); | 
					
						
							|  |  |  | 		undo_redo->add_undo_method(player, "rename_animation", new_name, current); | 
					
						
							|  |  |  | 		undo_redo->add_undo_method(anim.ptr(), "set_name", current); | 
					
						
							|  |  |  | 		undo_redo->add_do_method(this, "_animation_player_changed", player); | 
					
						
							|  |  |  | 		undo_redo->add_undo_method(this, "_animation_player_changed", player); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		undo_redo->commit_action(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		_select_anim_by_name(new_name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		Ref<Animation> new_anim = Ref<Animation>(memnew(Animation)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		new_anim->set_name(new_name); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 		undo_redo->create_action(TTR("Add Animation")); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		undo_redo->add_do_method(player, "add_animation", new_name, new_anim); | 
					
						
							|  |  |  | 		undo_redo->add_undo_method(player, "remove_animation", new_name); | 
					
						
							|  |  |  | 		undo_redo->add_do_method(this, "_animation_player_changed", player); | 
					
						
							|  |  |  | 		undo_redo->add_undo_method(this, "_animation_player_changed", player); | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 		if (animation->get_item_count() == 0) { | 
					
						
							|  |  |  | 			undo_redo->add_do_method(this, "_start_onion_skinning"); | 
					
						
							|  |  |  | 			undo_redo->add_undo_method(this, "_stop_onion_skinning"); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		undo_redo->commit_action(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		_select_anim_by_name(new_name); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	name_dialog->hide(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-07 17:27:52 +01:00
										 |  |  | void AnimationPlayerEditor::_blend_editor_next_changed(const int p_idx) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (animation->get_item_count() == 0) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String current = animation->get_item_text(animation->get_selected()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-07 17:27:52 +01:00
										 |  |  | 	undo_redo->create_action(TTR("Blend Next Changed")); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	undo_redo->add_do_method(player, "animation_set_next", current, blend_editor.next->get_item_text(p_idx)); | 
					
						
							|  |  |  | 	undo_redo->add_undo_method(player, "animation_set_next", current, player->animation_get_next(current)); | 
					
						
							|  |  |  | 	undo_redo->add_do_method(this, "_animation_player_changed", player); | 
					
						
							|  |  |  | 	undo_redo->add_undo_method(this, "_animation_player_changed", player); | 
					
						
							| 
									
										
										
										
											2016-05-07 17:27:52 +01:00
										 |  |  | 	undo_redo->commit_action(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_animation_blend() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (updating_blends) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	blend_editor.tree->clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (animation->get_item_count() == 0) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String current = animation->get_item_text(animation->get_selected()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-12 13:59:25 -05:00
										 |  |  | 	blend_editor.dialog->popup_centered(Size2(400, 400) * EDSCALE); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	blend_editor.tree->set_hide_root(true); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	blend_editor.tree->set_column_min_width(0, 10); | 
					
						
							|  |  |  | 	blend_editor.tree->set_column_min_width(1, 3); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	List<StringName> anims; | 
					
						
							|  |  |  | 	player->get_animation_list(&anims); | 
					
						
							|  |  |  | 	TreeItem *root = blend_editor.tree->create_item(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	updating_blends = true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-07 17:27:52 +01:00
										 |  |  | 	int i = 0; | 
					
						
							|  |  |  | 	bool anim_found = false; | 
					
						
							|  |  |  | 	blend_editor.next->clear(); | 
					
						
							|  |  |  | 	blend_editor.next->add_item("", i); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (List<StringName>::Element *E = anims.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		String to = E->get(); | 
					
						
							|  |  |  | 		TreeItem *blend = blend_editor.tree->create_item(root); | 
					
						
							|  |  |  | 		blend->set_editable(0, false); | 
					
						
							|  |  |  | 		blend->set_editable(1, true); | 
					
						
							|  |  |  | 		blend->set_text(0, to); | 
					
						
							|  |  |  | 		blend->set_cell_mode(1, TreeItem::CELL_MODE_RANGE); | 
					
						
							|  |  |  | 		blend->set_range_config(1, 0, 3600, 0.001); | 
					
						
							|  |  |  | 		blend->set_range(1, player->get_blend_time(current, to)); | 
					
						
							| 
									
										
										
										
											2016-05-07 17:27:52 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		i++; | 
					
						
							|  |  |  | 		blend_editor.next->add_item(to, i); | 
					
						
							|  |  |  | 		if (to == player->animation_get_next(current)) { | 
					
						
							|  |  |  | 			blend_editor.next->select(i); | 
					
						
							|  |  |  | 			anim_found = true; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-07 17:27:52 +01:00
										 |  |  | 	// make sure we reset it else it becomes out of sync and could contain a deleted animation
 | 
					
						
							|  |  |  | 	if (!anim_found) { | 
					
						
							|  |  |  | 		blend_editor.next->select(0); | 
					
						
							|  |  |  | 		player->animation_set_next(current, blend_editor.next->get_item_text(0)); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	updating_blends = false; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_blend_edited() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (updating_blends) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (animation->get_item_count() == 0) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String current = animation->get_item_text(animation->get_selected()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	TreeItem *selected = blend_editor.tree->get_edited(); | 
					
						
							|  |  |  | 	if (!selected) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	updating_blends = true; | 
					
						
							|  |  |  | 	String to = selected->get_text(0); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	float blend_time = selected->get_range(1); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	float prev_blend_time = player->get_blend_time(current, to); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 	undo_redo->create_action(TTR("Change Blend Time")); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	undo_redo->add_do_method(player, "set_blend_time", current, to, blend_time); | 
					
						
							|  |  |  | 	undo_redo->add_undo_method(player, "set_blend_time", current, to, prev_blend_time); | 
					
						
							|  |  |  | 	undo_redo->add_do_method(this, "_animation_player_changed", player); | 
					
						
							|  |  |  | 	undo_redo->add_undo_method(this, "_animation_player_changed", player); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	undo_redo->commit_action(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	updating_blends = false; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::ensure_visibility() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-01 11:37:58 +02:00
										 |  |  | 	if (player && pin->is_pressed()) | 
					
						
							|  |  |  | 		return; // another player is pinned, don't reset
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	_animation_edit(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-29 22:59:25 -03:00
										 |  |  | Dictionary AnimationPlayerEditor::get_state() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Dictionary d; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	d["visible"] = is_visible_in_tree(); | 
					
						
							| 
									
										
										
										
											2017-01-13 10:45:50 -03:00
										 |  |  | 	if (EditorNode::get_singleton()->get_edited_scene() && is_visible_in_tree() && player) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		d["player"] = EditorNode::get_singleton()->get_edited_scene()->get_path_to(player); | 
					
						
							| 
									
										
										
										
											2018-01-14 12:28:57 +02:00
										 |  |  | 		d["animation"] = player->get_assigned_animation(); | 
					
						
							| 
									
										
										
										
											2019-04-14 16:43:38 -03:00
										 |  |  | 		d["track_editor_state"] = track_editor->get_state(); | 
					
						
							| 
									
										
										
										
											2015-08-29 22:59:25 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return d; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void AnimationPlayerEditor::set_state(const Dictionary &p_state) { | 
					
						
							| 
									
										
										
										
											2015-08-29 22:59:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-24 22:47:16 -03:00
										 |  |  | 	if (!p_state.has("visible") || !p_state["visible"]) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!EditorNode::get_singleton()->get_edited_scene()) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-29 22:59:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-24 22:47:16 -03:00
										 |  |  | 	if (p_state.has("player")) { | 
					
						
							| 
									
										
										
										
											2016-02-21 11:52:11 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-29 22:59:25 -03:00
										 |  |  | 		Node *n = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["player"]); | 
					
						
							| 
									
										
										
										
											2017-08-24 22:58:51 +02:00
										 |  |  | 		if (Object::cast_to<AnimationPlayer>(n) && EditorNode::get_singleton()->get_editor_selection()->is_selected(n)) { | 
					
						
							|  |  |  | 			player = Object::cast_to<AnimationPlayer>(n); | 
					
						
							| 
									
										
										
										
											2015-08-29 22:59:25 -03:00
										 |  |  | 			_update_player(); | 
					
						
							| 
									
										
										
										
											2019-05-27 12:12:51 -03:00
										 |  |  | 			editor->make_bottom_panel_item_visible(this); | 
					
						
							| 
									
										
										
										
											2015-08-29 22:59:25 -03:00
										 |  |  | 			set_process(true); | 
					
						
							|  |  |  | 			ensure_visibility(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (p_state.has("animation")) { | 
					
						
							|  |  |  | 				String anim = p_state["animation"]; | 
					
						
							| 
									
										
										
										
											2019-09-04 18:18:25 +02:00
										 |  |  | 				if (!anim.empty() && player->has_animation(anim)) { | 
					
						
							|  |  |  | 					_select_anim_by_name(anim); | 
					
						
							|  |  |  | 					_animation_edit(); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-08-29 22:59:25 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-05-24 22:47:16 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-04-14 16:43:38 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-24 22:47:16 -03:00
										 |  |  | 	if (p_state.has("track_editor_state")) { | 
					
						
							|  |  |  | 		track_editor->set_state(p_state["track_editor_state"]); | 
					
						
							| 
									
										
										
										
											2015-08-29 22:59:25 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void AnimationPlayerEditor::_animation_resource_edit() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (animation->get_item_count()) { | 
					
						
							|  |  |  | 		String current = animation->get_item_text(animation->get_selected()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		Ref<Animation> anim = player->get_animation(current); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		editor->edit_resource(anim); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_animation_edit() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 	if (animation->get_item_count()) { | 
					
						
							|  |  |  | 		String current = animation->get_item_text(animation->get_selected()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		Ref<Animation> anim = player->get_animation(current); | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 		track_editor->set_animation(anim); | 
					
						
							| 
									
										
										
										
											2019-05-24 22:47:16 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 		Node *root = player->get_node(player->get_root()); | 
					
						
							|  |  |  | 		if (root) { | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 			track_editor->set_root(root); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 		track_editor->set_animation(Ref<Animation>()); | 
					
						
							|  |  |  | 		track_editor->set_root(NULL); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-05-24 22:47:16 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | void AnimationPlayerEditor::_dialog_action(String p_file) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 	switch (current_option) { | 
					
						
							|  |  |  | 		case RESOURCE_LOAD: { | 
					
						
							|  |  |  | 			ERR_FAIL_COND(!player); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 			Ref<Resource> res = ResourceLoader::load(p_file, "Animation"); | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 			ERR_FAIL_COND_MSG(res.is_null(), "Cannot load Animation from file '" + p_file + "'."); | 
					
						
							|  |  |  | 			ERR_FAIL_COND_MSG(!res->is_class("Animation"), "Loaded resource from file '" + p_file + "' is not Animation."); | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 			if (p_file.find_last("/") != -1) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 				p_file = p_file.substr(p_file.find_last("/") + 1, p_file.length()); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (p_file.find_last("\\") != -1) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 				p_file = p_file.substr(p_file.find_last("\\") + 1, p_file.length()); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 			if (p_file.find(".") != -1) | 
					
						
							|  |  |  | 				p_file = p_file.substr(0, p_file.find(".")); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 			undo_redo->create_action(TTR("Load Animation")); | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 			undo_redo->add_do_method(player, "add_animation", p_file, res); | 
					
						
							|  |  |  | 			undo_redo->add_undo_method(player, "remove_animation", p_file); | 
					
						
							|  |  |  | 			if (player->has_animation(p_file)) { | 
					
						
							|  |  |  | 				undo_redo->add_undo_method(player, "add_animation", p_file, player->get_animation(p_file)); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			undo_redo->add_do_method(this, "_animation_player_changed", player); | 
					
						
							|  |  |  | 			undo_redo->add_undo_method(this, "_animation_player_changed", player); | 
					
						
							|  |  |  | 			undo_redo->commit_action(); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case RESOURCE_SAVE: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			String current = animation->get_item_text(animation->get_selected()); | 
					
						
							|  |  |  | 			if (current != "") { | 
					
						
							|  |  |  | 				Ref<Animation> anim = player->get_animation(current); | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-11 14:49:34 +02:00
										 |  |  | 				ERR_FAIL_COND(!Object::cast_to<Resource>(*anim)); | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-24 22:58:51 +02:00
										 |  |  | 				RES current_res = RES(Object::cast_to<Resource>(*anim)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 				_animation_save_in_path(current_res, p_file); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void AnimationPlayerEditor::_scale_changed(const String &p_scale) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-13 19:36:04 -03:00
										 |  |  | 	player->set_speed_scale(p_scale.to_double()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_update_animation() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// the purpose of _update_animation is to reflect the current state
 | 
					
						
							|  |  |  | 	// of the animation player in the current editor..
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	updating = true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (player->is_playing()) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		play->set_pressed(true); | 
					
						
							|  |  |  | 		stop->set_pressed(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		play->set_pressed(false); | 
					
						
							|  |  |  | 		stop->set_pressed(true); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	scale->set_text(String::num(player->get_speed_scale(), 2)); | 
					
						
							| 
									
										
										
										
											2018-01-14 12:28:57 +02:00
										 |  |  | 	String current = player->get_assigned_animation(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < animation->get_item_count(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (animation->get_item_text(i) == current) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			animation->select(i); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	updating = false; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_update_player() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	updating = true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	List<StringName> animlist; | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 	if (player) | 
					
						
							|  |  |  | 		player->get_animation_list(&animlist); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	animation->clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | #define ITEM_DISABLED(m_item, m_disabled) tool_anim->get_popup()->set_item_disabled(tool_anim->get_popup()->get_item_index(m_item), m_disabled)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ITEM_DISABLED(TOOL_SAVE_ANIM, animlist.size() == 0); | 
					
						
							|  |  |  | 	ITEM_DISABLED(TOOL_SAVE_AS_ANIM, animlist.size() == 0); | 
					
						
							|  |  |  | 	ITEM_DISABLED(TOOL_DUPLICATE_ANIM, animlist.size() == 0); | 
					
						
							|  |  |  | 	ITEM_DISABLED(TOOL_RENAME_ANIM, animlist.size() == 0); | 
					
						
							|  |  |  | 	ITEM_DISABLED(TOOL_EDIT_TRANSITIONS, animlist.size() == 0); | 
					
						
							|  |  |  | 	ITEM_DISABLED(TOOL_COPY_ANIM, animlist.size() == 0); | 
					
						
							|  |  |  | 	ITEM_DISABLED(TOOL_REMOVE_ANIM, animlist.size() == 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	stop->set_disabled(animlist.size() == 0); | 
					
						
							|  |  |  | 	play->set_disabled(animlist.size() == 0); | 
					
						
							|  |  |  | 	play_bw->set_disabled(animlist.size() == 0); | 
					
						
							|  |  |  | 	play_bw_from->set_disabled(animlist.size() == 0); | 
					
						
							|  |  |  | 	play_from->set_disabled(animlist.size() == 0); | 
					
						
							| 
									
										
										
										
											2018-04-26 22:58:30 -03:00
										 |  |  | 	frame->set_editable(animlist.size() != 0); | 
					
						
							|  |  |  | 	animation->set_disabled(animlist.size() == 0); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	autoplay->set_disabled(animlist.size() == 0); | 
					
						
							|  |  |  | 	tool_anim->set_disabled(player == NULL); | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	onion_toggle->set_disabled(animlist.size() == 0); | 
					
						
							|  |  |  | 	onion_skinning->set_disabled(animlist.size() == 0); | 
					
						
							| 
									
										
										
										
											2018-04-27 16:05:10 -03:00
										 |  |  | 	pin->set_disabled(player == NULL); | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-04 22:00:16 +02:00
										 |  |  | 	if (!player) { | 
					
						
							|  |  |  | 		AnimationPlayerEditor::singleton->get_track_editor()->update_keying(); | 
					
						
							|  |  |  | 		EditorNode::get_singleton()->update_keying(); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	int active_idx = -1; | 
					
						
							|  |  |  | 	for (List<StringName>::Element *E = animlist.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (player->get_autoplay() == E->get()) | 
					
						
							|  |  |  | 			animation->add_icon_item(autoplay_icon, E->get()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		else | 
					
						
							|  |  |  | 			animation->add_item(E->get()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 12:28:57 +02:00
										 |  |  | 		if (player->get_assigned_animation() == E->get()) | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			active_idx = animation->get_item_count() - 1; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	updating = false; | 
					
						
							|  |  |  | 	if (active_idx != -1) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		animation->select(active_idx); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		autoplay->set_pressed(animation->get_item_text(active_idx) == player->get_autoplay()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		_animation_selected(active_idx); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	} else if (animation->get_item_count() > 0) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		animation->select(0); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		autoplay->set_pressed(animation->get_item_text(0) == player->get_autoplay()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		_animation_selected(0); | 
					
						
							| 
									
										
										
										
											2018-07-03 15:57:54 -03:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		_animation_selected(0); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 	if (animation->get_item_count()) { | 
					
						
							|  |  |  | 		String current = animation->get_item_text(animation->get_selected()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		Ref<Animation> anim = player->get_animation(current); | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 		track_editor->set_animation(anim); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 		Node *root = player->get_node(player->get_root()); | 
					
						
							|  |  |  | 		if (root) { | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 			track_editor->set_root(root); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_update_animation(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::edit(AnimationPlayer *p_player) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (player && pin->is_pressed()) | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 		return; // Ignore, pinned.
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	player = p_player; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-22 09:42:12 -03:00
										 |  |  | 	if (player) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		_update_player(); | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (onion.enabled) { | 
					
						
							|  |  |  | 			if (animation->get_item_count() > 0) | 
					
						
							|  |  |  | 				_start_onion_skinning(); | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				_stop_onion_skinning(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 		track_editor->show_select_node_warning(false); | 
					
						
							| 
									
										
										
										
											2016-07-22 09:42:12 -03:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 		if (onion.enabled) | 
					
						
							|  |  |  | 			_stop_onion_skinning(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 		track_editor->show_select_node_warning(true); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-18 20:00:07 +02:00
										 |  |  | void AnimationPlayerEditor::forward_canvas_force_draw_over_viewport(Control *p_overlay) { | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!onion.can_overlay) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	// Can happen on viewport resize, at least.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	if (!_are_onion_layers_valid()) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	RID ci = p_overlay->get_canvas_item(); | 
					
						
							|  |  |  | 	Rect2 src_rect = p_overlay->get_global_rect(); | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	// Re-flip since captures are already flipped.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	src_rect.position.y = onion.capture_size.y - (src_rect.position.y + src_rect.size.y); | 
					
						
							|  |  |  | 	src_rect.size.y *= -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Rect2 dst_rect = Rect2(Point2(), p_overlay->get_size()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	float alpha_step = 1.0 / (onion.steps + 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int cidx = 0; | 
					
						
							|  |  |  | 	if (onion.past) { | 
					
						
							|  |  |  | 		float alpha = 0; | 
					
						
							|  |  |  | 		do { | 
					
						
							|  |  |  | 			alpha += alpha_step; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (onion.captures_valid[cidx]) { | 
					
						
							|  |  |  | 				VS::get_singleton()->canvas_item_add_texture_rect_region( | 
					
						
							|  |  |  | 						ci, dst_rect, VS::get_singleton()->viewport_get_texture(onion.captures[cidx]), src_rect, Color(1, 1, 1, alpha)); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			cidx++; | 
					
						
							|  |  |  | 		} while (cidx < onion.steps); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (onion.future) { | 
					
						
							|  |  |  | 		float alpha = 1; | 
					
						
							|  |  |  | 		int base_cidx = cidx; | 
					
						
							|  |  |  | 		do { | 
					
						
							|  |  |  | 			alpha -= alpha_step; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (onion.captures_valid[cidx]) { | 
					
						
							|  |  |  | 				VS::get_singleton()->canvas_item_add_texture_rect_region( | 
					
						
							|  |  |  | 						ci, dst_rect, VS::get_singleton()->viewport_get_texture(onion.captures[cidx]), src_rect, Color(1, 1, 1, alpha)); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			cidx++; | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 		} while (cidx < base_cidx + onion.steps); // In case there's the present capture at the end, skip it.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void AnimationPlayerEditor::_animation_duplicate() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!animation->get_item_count()) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String current = animation->get_item_text(animation->get_selected()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Ref<Animation> anim = player->get_animation(current); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (!anim.is_valid()) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Ref<Animation> new_anim = memnew(Animation); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	List<PropertyInfo> plist; | 
					
						
							|  |  |  | 	anim->get_property_list(&plist); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (E->get().usage & PROPERTY_USAGE_STORAGE) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			new_anim->set(E->get().name, anim->get(E->get().name)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	new_anim->set_path(""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String new_name = current; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while (player->has_animation(new_name)) { | 
					
						
							|  |  |  | 		new_name = new_name + " (copy)"; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-01-13 13:21:46 +01:00
										 |  |  | 	new_anim->set_name(new_name); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 	undo_redo->create_action(TTR("Duplicate Animation")); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	undo_redo->add_do_method(player, "add_animation", new_name, new_anim); | 
					
						
							|  |  |  | 	undo_redo->add_undo_method(player, "remove_animation", new_name); | 
					
						
							|  |  |  | 	undo_redo->add_do_method(player, "animation_set_next", new_name, player->animation_get_next(current)); | 
					
						
							|  |  |  | 	undo_redo->add_do_method(this, "_animation_player_changed", player); | 
					
						
							|  |  |  | 	undo_redo->add_undo_method(this, "_animation_player_changed", player); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	undo_redo->commit_action(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < animation->get_item_count(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (animation->get_item_text(i) == new_name) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			animation->select(i); | 
					
						
							|  |  |  | 			_animation_selected(i); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (updating || !player || player->is_playing()) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	updating = true; | 
					
						
							| 
									
										
										
										
											2019-08-06 01:15:20 +02:00
										 |  |  | 	String current = player->get_assigned_animation(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (current == "" || !player->has_animation(current)) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		updating = false; | 
					
						
							|  |  |  | 		current = ""; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Ref<Animation> anim; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	anim = player->get_animation(current); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-06 01:15:20 +02:00
										 |  |  | 	float pos = CLAMP(anim->get_length() * (p_value / frame->get_max()), 0, anim->get_length()); | 
					
						
							|  |  |  | 	if (track_editor->is_snap_enabled()) { | 
					
						
							| 
									
										
										
										
											2019-09-02 15:49:55 +02:00
										 |  |  | 		pos = Math::stepify(pos, _get_editor_step()); | 
					
						
							| 
									
										
										
										
											2016-02-09 15:02:57 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-19 01:43:02 -03:00
										 |  |  | 	if (player->is_valid() && !p_set) { | 
					
						
							| 
									
										
										
										
											2017-09-10 15:37:49 +02:00
										 |  |  | 		float cpos = player->get_current_animation_position(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		player->seek_delta(pos, pos - cpos); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2018-03-09 18:42:24 +01:00
										 |  |  | 		player->stop(true); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		player->seek(pos, true); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 	track_editor->set_anim_pos(pos); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	updating = true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_animation_player_changed(Object *p_pl) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (player == p_pl && is_visible_in_tree()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		_update_player(); | 
					
						
							| 
									
										
										
										
											2017-01-13 10:45:50 -03:00
										 |  |  | 		if (blend_editor.dialog->is_visible_in_tree()) | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 			_animation_blend(); // Update.
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_list_changed() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (is_visible_in_tree()) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		_update_player(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-31 04:43:46 +09:00
										 |  |  | void AnimationPlayerEditor::_animation_key_editor_anim_len_changed(float p_len) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	frame->set_max(p_len); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-01 18:38:03 +02:00
										 |  |  | 	timeline_position = p_pos; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-13 10:45:50 -03:00
										 |  |  | 	if (!is_visible_in_tree()) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2019-10-02 22:49:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (!player) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (player->is_playing()) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-02 22:49:34 +02:00
										 |  |  | 	if (!player->has_animation(player->get_assigned_animation())) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	updating = true; | 
					
						
							| 
									
										
										
										
											2019-09-02 15:49:55 +02:00
										 |  |  | 	frame->set_value(Math::stepify(p_pos, _get_editor_step())); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	updating = false; | 
					
						
							|  |  |  | 	_seek_value_changed(p_pos, !p_drag); | 
					
						
							| 
									
										
										
										
											2016-06-19 01:43:02 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-15 17:12:35 -03:00
										 |  |  | 	EditorNode::get_singleton()->get_inspector()->refresh(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | void AnimationPlayerEditor::_animation_tool_menu(int p_option) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-01 15:26:29 +07:00
										 |  |  | 	String current; | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) { | 
					
						
							| 
									
										
										
										
											2018-07-01 15:26:29 +07:00
										 |  |  | 		current = animation->get_item_text(animation->get_selected()); | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-07-01 15:26:29 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 	Ref<Animation> anim; | 
					
						
							| 
									
										
										
										
											2018-07-01 15:26:29 +07:00
										 |  |  | 	if (current != String()) { | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 		anim = player->get_animation(current); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	switch (p_option) { | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 		case TOOL_NEW_ANIM: { | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 			_animation_new(); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case TOOL_LOAD_ANIM: { | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 			_animation_load(); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case TOOL_SAVE_ANIM: { | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 			if (anim.is_valid()) { | 
					
						
							|  |  |  | 				_animation_save(anim); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case TOOL_SAVE_AS_ANIM: { | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 			if (anim.is_valid()) { | 
					
						
							|  |  |  | 				_animation_save_as(anim); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case TOOL_DUPLICATE_ANIM: { | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 			_animation_duplicate(); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case TOOL_RENAME_ANIM: { | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 			_animation_rename(); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case TOOL_EDIT_TRANSITIONS: { | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 			_animation_blend(); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case TOOL_REMOVE_ANIM: { | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 			_animation_remove(); | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 		case TOOL_COPY_ANIM: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!animation->get_item_count()) { | 
					
						
							| 
									
										
										
										
											2018-04-26 22:58:30 -03:00
										 |  |  | 				error_dialog->set_text(TTR("No animation to copy!")); | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 				error_dialog->popup_centered_minsize(); | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 			String current2 = animation->get_item_text(animation->get_selected()); | 
					
						
							|  |  |  | 			Ref<Animation> anim2 = player->get_animation(current2); | 
					
						
							|  |  |  | 			EditorSettings::get_singleton()->set_resource_clipboard(anim2); | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 		} break; | 
					
						
							|  |  |  | 		case TOOL_PASTE_ANIM: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 			Ref<Animation> anim2 = EditorSettings::get_singleton()->get_resource_clipboard(); | 
					
						
							|  |  |  | 			if (!anim2.is_valid()) { | 
					
						
							| 
									
										
										
										
											2018-04-26 22:58:30 -03:00
										 |  |  | 				error_dialog->set_text(TTR("No animation resource on clipboard!")); | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 				error_dialog->popup_centered_minsize(); | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 			String name = anim2->get_name(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (name == "") { | 
					
						
							|  |  |  | 				name = TTR("Pasted Animation"); | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			int idx = 1; | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 			String base = name; | 
					
						
							|  |  |  | 			while (player->has_animation(name)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				idx++; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				name = base + " " + itos(idx); | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 			undo_redo->create_action(TTR("Paste Animation")); | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 			undo_redo->add_do_method(player, "add_animation", name, anim2); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			undo_redo->add_undo_method(player, "remove_animation", name); | 
					
						
							|  |  |  | 			undo_redo->add_do_method(this, "_animation_player_changed", player); | 
					
						
							|  |  |  | 			undo_redo->add_undo_method(this, "_animation_player_changed", player); | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 			undo_redo->commit_action(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			_select_anim_by_name(name); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case TOOL_EDIT_RESOURCE: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!animation->get_item_count()) { | 
					
						
							| 
									
										
										
										
											2018-04-26 22:58:30 -03:00
										 |  |  | 				error_dialog->set_text(TTR("No animation to edit!")); | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 				error_dialog->popup_centered_minsize(); | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 			String current2 = animation->get_item_text(animation->get_selected()); | 
					
						
							|  |  |  | 			Ref<Animation> anim2 = player->get_animation(current2); | 
					
						
							|  |  |  | 			editor->edit_resource(anim2); | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 		} break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | void AnimationPlayerEditor::_onion_skinning_menu(int p_option) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PopupMenu *menu = onion_skinning->get_popup(); | 
					
						
							|  |  |  | 	int idx = menu->get_item_index(p_option); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (p_option) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case ONION_SKINNING_ENABLE: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			onion.enabled = !onion.enabled; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (onion.enabled) | 
					
						
							|  |  |  | 				_start_onion_skinning(); | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				_stop_onion_skinning(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case ONION_SKINNING_PAST: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 			// Ensure at least one of past/future is checked.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 			onion.past = onion.future ? !onion.past : true; | 
					
						
							|  |  |  | 			menu->set_item_checked(idx, onion.past); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case ONION_SKINNING_FUTURE: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 			// Ensure at least one of past/future is checked.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 			onion.future = onion.past ? !onion.future : true; | 
					
						
							|  |  |  | 			menu->set_item_checked(idx, onion.future); | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 		case ONION_SKINNING_1_STEP: // Fall-through.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 		case ONION_SKINNING_2_STEPS: | 
					
						
							|  |  |  | 		case ONION_SKINNING_3_STEPS: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			onion.steps = (p_option - ONION_SKINNING_1_STEP) + 1; | 
					
						
							|  |  |  | 			int one_frame_idx = menu->get_item_index(ONION_SKINNING_1_STEP); | 
					
						
							|  |  |  | 			for (int i = 0; i <= ONION_SKINNING_LAST_STEPS_OPTION - ONION_SKINNING_1_STEP; i++) { | 
					
						
							|  |  |  | 				menu->set_item_checked(one_frame_idx + i, onion.steps == i + 1); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case ONION_SKINNING_DIFFERENCES_ONLY: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			onion.differences_only = !onion.differences_only; | 
					
						
							|  |  |  | 			menu->set_item_checked(idx, onion.differences_only); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case ONION_SKINNING_FORCE_WHITE_MODULATE: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			onion.force_white_modulate = !onion.force_white_modulate; | 
					
						
							|  |  |  | 			menu->set_item_checked(idx, onion.force_white_modulate); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case ONION_SKINNING_INCLUDE_GIZMOS: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			onion.include_gizmos = !onion.include_gizmos; | 
					
						
							|  |  |  | 			menu->set_item_checked(idx, onion.include_gizmos); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | void AnimationPlayerEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) { | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 	Ref<InputEventKey> k = p_ev; | 
					
						
							|  |  |  | 	if (is_visible_in_tree() && k.is_valid() && k->is_pressed() && !k->is_echo() && !k->get_alt() && !k->get_control() && !k->get_metakey()) { | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 		switch (k->get_scancode()) { | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			case KEY_A: { | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 				if (!k->get_shift()) | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 					_play_bw_from_pressed(); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					_play_bw_pressed(); | 
					
						
							|  |  |  | 			} break; | 
					
						
							|  |  |  | 			case KEY_S: { | 
					
						
							|  |  |  | 				_stop_pressed(); | 
					
						
							|  |  |  | 			} break; | 
					
						
							|  |  |  | 			case KEY_D: { | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 				if (!k->get_shift()) | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 					_play_from_pressed(); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					_play_pressed(); | 
					
						
							|  |  |  | 			} break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | void AnimationPlayerEditor::_editor_visibility_changed() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	if (is_visible() && animation->get_item_count() > 0) { | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 		_start_onion_skinning(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool AnimationPlayerEditor::_are_onion_layers_valid() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!onion.past && !onion.future, false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Point2 capture_size = get_tree()->get_root()->get_size(); | 
					
						
							|  |  |  | 	return onion.captures.size() == onion.get_needed_capture_count() && onion.capture_size == capture_size; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_allocate_onion_layers() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_free_onion_layers(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int captures = onion.get_needed_capture_count(); | 
					
						
							|  |  |  | 	Point2 capture_size = get_tree()->get_root()->get_size(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	onion.captures.resize(captures); | 
					
						
							|  |  |  | 	onion.captures_valid.resize(captures); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int i = 0; i < captures; i++) { | 
					
						
							|  |  |  | 		bool is_present = onion.differences_only && i == captures - 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 		// Each capture is a viewport with a canvas item attached that renders a full-size rect with the contents of the main viewport.
 | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 		onion.captures.write[i] = VS::get_singleton()->viewport_create(); | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 		VS::get_singleton()->viewport_set_usage(onion.captures[i], VS::VIEWPORT_USAGE_2D); | 
					
						
							|  |  |  | 		VS::get_singleton()->viewport_set_size(onion.captures[i], capture_size.width, capture_size.height); | 
					
						
							|  |  |  | 		VS::get_singleton()->viewport_set_update_mode(onion.captures[i], VS::VIEWPORT_UPDATE_ALWAYS); | 
					
						
							|  |  |  | 		VS::get_singleton()->viewport_set_transparent_background(onion.captures[i], !is_present); | 
					
						
							|  |  |  | 		VS::get_singleton()->viewport_set_vflip(onion.captures[i], true); | 
					
						
							|  |  |  | 		VS::get_singleton()->viewport_attach_canvas(onion.captures[i], onion.capture.canvas); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	// Reset the capture canvas item to the current root viewport texture (defensive).
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	VS::get_singleton()->canvas_item_clear(onion.capture.canvas_item); | 
					
						
							|  |  |  | 	VS::get_singleton()->canvas_item_add_texture_rect(onion.capture.canvas_item, Rect2(Point2(), capture_size), get_tree()->get_root()->get_texture()->get_rid()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	onion.capture_size = capture_size; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_free_onion_layers() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int i = 0; i < onion.captures.size(); i++) { | 
					
						
							|  |  |  | 		if (onion.captures[i].is_valid()) { | 
					
						
							|  |  |  | 			VS::get_singleton()->free(onion.captures[i]); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	onion.captures.clear(); | 
					
						
							|  |  |  | 	onion.captures_valid.clear(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_prepare_onion_layers_1() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	// This would be called per viewport and we want to act once only.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	int64_t frame = get_tree()->get_frame(); | 
					
						
							|  |  |  | 	if (frame == onion.last_frame) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!onion.enabled || !is_processing() || !is_visible() || !get_player()) { | 
					
						
							|  |  |  | 		_stop_onion_skinning(); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	onion.last_frame = frame; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	// Refresh viewports with no onion layers overlaid.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	onion.can_overlay = false; | 
					
						
							|  |  |  | 	plugin->update_overlays(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (player->is_playing()) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	// And go to next step afterwards.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	call_deferred("_prepare_onion_layers_2"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_prepare_onion_layers_2() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 12:28:57 +02:00
										 |  |  | 	Ref<Animation> anim = player->get_animation(player->get_assigned_animation()); | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	if (!anim.is_valid()) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!_are_onion_layers_valid()) | 
					
						
							|  |  |  | 		_allocate_onion_layers(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	// Hide superfluous elements that would make the overlay unnecessary cluttered.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	Dictionary canvas_edit_state; | 
					
						
							|  |  |  | 	Dictionary spatial_edit_state; | 
					
						
							|  |  |  | 	if (SpatialEditor::get_singleton()->is_visible()) { | 
					
						
							|  |  |  | 		// 3D
 | 
					
						
							|  |  |  | 		spatial_edit_state = SpatialEditor::get_singleton()->get_state(); | 
					
						
							| 
									
										
										
										
											2017-12-17 16:07:15 -06:00
										 |  |  | 		Dictionary new_state = spatial_edit_state.duplicate(); | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 		new_state["show_grid"] = false; | 
					
						
							|  |  |  | 		new_state["show_origin"] = false; | 
					
						
							|  |  |  | 		Array orig_vp = spatial_edit_state["viewports"]; | 
					
						
							|  |  |  | 		Array vp; | 
					
						
							|  |  |  | 		vp.resize(4); | 
					
						
							|  |  |  | 		for (int i = 0; i < vp.size(); i++) { | 
					
						
							| 
									
										
										
										
											2017-12-17 16:07:15 -06:00
										 |  |  | 			Dictionary d = ((Dictionary)orig_vp[i]).duplicate(); | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 			d["use_environment"] = false; | 
					
						
							|  |  |  | 			d["doppler"] = false; | 
					
						
							|  |  |  | 			d["gizmos"] = onion.include_gizmos ? d["gizmos"] : Variant(false); | 
					
						
							|  |  |  | 			d["information"] = false; | 
					
						
							|  |  |  | 			vp[i] = d; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		new_state["viewports"] = vp; | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 		// TODO: Save/restore only affected entries.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 		SpatialEditor::get_singleton()->set_state(new_state); | 
					
						
							|  |  |  | 	} else { // CanvasItemEditor
 | 
					
						
							|  |  |  | 		// 2D
 | 
					
						
							|  |  |  | 		canvas_edit_state = CanvasItemEditor::get_singleton()->get_state(); | 
					
						
							| 
									
										
										
										
											2017-12-17 16:07:15 -06:00
										 |  |  | 		Dictionary new_state = canvas_edit_state.duplicate(); | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 		new_state["show_grid"] = false; | 
					
						
							|  |  |  | 		new_state["show_rulers"] = false; | 
					
						
							|  |  |  | 		new_state["show_guides"] = false; | 
					
						
							|  |  |  | 		new_state["show_helpers"] = false; | 
					
						
							| 
									
										
										
										
											2019-05-20 22:36:34 +02:00
										 |  |  | 		new_state["show_zoom_control"] = false; | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 		// TODO: Save/restore only affected entries.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 		CanvasItemEditor::get_singleton()->set_state(new_state); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	// Tweak the root viewport to ensure it's rendered before our target.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	RID root_vp = get_tree()->get_root()->get_viewport_rid(); | 
					
						
							|  |  |  | 	Rect2 root_vp_screen_rect = get_tree()->get_root()->get_attach_to_screen_rect(); | 
					
						
							|  |  |  | 	VS::get_singleton()->viewport_attach_to_screen(root_vp, Rect2()); | 
					
						
							|  |  |  | 	VS::get_singleton()->viewport_set_update_mode(root_vp, VS::VIEWPORT_UPDATE_ALWAYS); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	RID present_rid; | 
					
						
							|  |  |  | 	if (onion.differences_only) { | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 		// Capture present scene as it is.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 		VS::get_singleton()->canvas_item_set_material(onion.capture.canvas_item, RID()); | 
					
						
							|  |  |  | 		present_rid = onion.captures[onion.captures.size() - 1]; | 
					
						
							|  |  |  | 		VS::get_singleton()->viewport_set_active(present_rid, true); | 
					
						
							|  |  |  | 		VS::get_singleton()->viewport_set_parent_viewport(root_vp, present_rid); | 
					
						
							|  |  |  | 		VS::get_singleton()->draw(false); | 
					
						
							|  |  |  | 		VS::get_singleton()->viewport_set_active(present_rid, false); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	// Backup current animation state.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	AnimatedValuesBackup values_backup = player->backup_animated_values(); | 
					
						
							|  |  |  | 	float cpos = player->get_current_animation_position(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	// Render every past/future step with the capture shader.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	VS::get_singleton()->canvas_item_set_material(onion.capture.canvas_item, onion.capture.material->get_rid()); | 
					
						
							|  |  |  | 	onion.capture.material->set_shader_param("bkg_color", GLOBAL_GET("rendering/environment/default_clear_color")); | 
					
						
							|  |  |  | 	onion.capture.material->set_shader_param("differences_only", onion.differences_only); | 
					
						
							|  |  |  | 	onion.capture.material->set_shader_param("present", onion.differences_only ? VS::get_singleton()->viewport_get_texture(present_rid) : RID()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int step_off_a = onion.past ? -onion.steps : 0; | 
					
						
							|  |  |  | 	int step_off_b = onion.future ? onion.steps : 0; | 
					
						
							|  |  |  | 	int cidx = 0; | 
					
						
							|  |  |  | 	onion.capture.material->set_shader_param("dir_color", onion.force_white_modulate ? Color(1, 1, 1) : Color(EDITOR_GET("editors/animation/onion_layers_past_color"))); | 
					
						
							|  |  |  | 	for (int step_off = step_off_a; step_off <= step_off_b; step_off++) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (step_off == 0) { | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 			// Skip present step and switch to the color of future.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 			if (!onion.force_white_modulate) | 
					
						
							|  |  |  | 				onion.capture.material->set_shader_param("dir_color", EDITOR_GET("editors/animation/onion_layers_future_color")); | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		float pos = cpos + step_off * anim->get_step(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 		bool valid = anim->has_loop() || (pos >= 0 && pos <= anim->get_length()); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 		onion.captures_valid.write[cidx] = valid; | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 		if (valid) { | 
					
						
							|  |  |  | 			player->seek(pos, true); | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 			get_tree()->flush_transform_notifications(); // Needed for transforms of Spatials.
 | 
					
						
							|  |  |  | 			values_backup.update_skeletons(); // Needed for Skeletons (2D & 3D).
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			VS::get_singleton()->viewport_set_active(onion.captures[cidx], true); | 
					
						
							|  |  |  | 			VS::get_singleton()->viewport_set_parent_viewport(root_vp, onion.captures[cidx]); | 
					
						
							|  |  |  | 			VS::get_singleton()->draw(false); | 
					
						
							|  |  |  | 			VS::get_singleton()->viewport_set_active(onion.captures[cidx], false); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		cidx++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	// Restore root viewport.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	VS::get_singleton()->viewport_set_parent_viewport(root_vp, RID()); | 
					
						
							|  |  |  | 	VS::get_singleton()->viewport_attach_to_screen(root_vp, root_vp_screen_rect); | 
					
						
							|  |  |  | 	VS::get_singleton()->viewport_set_update_mode(root_vp, VS::VIEWPORT_UPDATE_WHEN_VISIBLE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Restore animation state
 | 
					
						
							|  |  |  | 	// (Seeking with update=true wouldn't do the trick because the current value of the properties
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	// may not match their value for the current point in the animation).
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	player->seek(cpos, false); | 
					
						
							|  |  |  | 	player->restore_animated_values(values_backup); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-04 02:20:57 -03:00
										 |  |  | 	// Restore state of main editors.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	if (SpatialEditor::get_singleton()->is_visible()) { | 
					
						
							|  |  |  | 		// 3D
 | 
					
						
							|  |  |  | 		SpatialEditor::get_singleton()->set_state(spatial_edit_state); | 
					
						
							|  |  |  | 	} else { // CanvasItemEditor
 | 
					
						
							|  |  |  | 		// 2D
 | 
					
						
							|  |  |  | 		CanvasItemEditor::get_singleton()->set_state(canvas_edit_state); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	// Update viewports with skin layers overlaid for the actual engine loop render.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	onion.can_overlay = true; | 
					
						
							|  |  |  | 	plugin->update_overlays(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_start_onion_skinning() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	// FIXME: Using "idle_frame" makes onion layers update one frame behind the current.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	if (!get_tree()->is_connected("idle_frame", this, "call_deferred")) { | 
					
						
							|  |  |  | 		get_tree()->connect("idle_frame", this, "call_deferred", varray("_prepare_onion_layers_1")); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditor::_stop_onion_skinning() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (get_tree()->is_connected("idle_frame", this, "call_deferred")) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		get_tree()->disconnect("idle_frame", this, "call_deferred"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		_free_onion_layers(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-04 02:20:57 -03:00
										 |  |  | 		// Clean up the overlay.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 		onion.can_overlay = false; | 
					
						
							|  |  |  | 		plugin->update_overlays(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | void AnimationPlayerEditor::_pin_pressed() { | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 	EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor()->update_tree(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void AnimationPlayerEditor::_bind_methods() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("_node_removed"), &AnimationPlayerEditor::_node_removed); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_play_pressed"), &AnimationPlayerEditor::_play_pressed); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_play_from_pressed"), &AnimationPlayerEditor::_play_from_pressed); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_play_bw_pressed"), &AnimationPlayerEditor::_play_bw_pressed); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_play_bw_from_pressed"), &AnimationPlayerEditor::_play_bw_from_pressed); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_stop_pressed"), &AnimationPlayerEditor::_stop_pressed); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_autoplay_pressed"), &AnimationPlayerEditor::_autoplay_pressed); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_animation_selected"), &AnimationPlayerEditor::_animation_selected); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_animation_name_edited"), &AnimationPlayerEditor::_animation_name_edited); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_animation_new"), &AnimationPlayerEditor::_animation_new); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_animation_rename"), &AnimationPlayerEditor::_animation_rename); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_animation_load"), &AnimationPlayerEditor::_animation_load); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_animation_remove"), &AnimationPlayerEditor::_animation_remove); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_animation_remove_confirmed"), &AnimationPlayerEditor::_animation_remove_confirmed); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_animation_blend"), &AnimationPlayerEditor::_animation_blend); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_animation_edit"), &AnimationPlayerEditor::_animation_edit); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_animation_resource_edit"), &AnimationPlayerEditor::_animation_resource_edit); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_dialog_action"), &AnimationPlayerEditor::_dialog_action); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_seek_value_changed"), &AnimationPlayerEditor::_seek_value_changed, DEFVAL(true)); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_animation_player_changed"), &AnimationPlayerEditor::_animation_player_changed); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_blend_edited"), &AnimationPlayerEditor::_blend_edited); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_scale_changed"), &AnimationPlayerEditor::_scale_changed); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_list_changed"), &AnimationPlayerEditor::_list_changed); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_animation_key_editor_seek"), &AnimationPlayerEditor::_animation_key_editor_seek); | 
					
						
							| 
									
										
										
										
											2019-05-31 04:43:46 +09:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("_animation_key_editor_anim_len_changed"), &AnimationPlayerEditor::_animation_key_editor_anim_len_changed); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("_animation_duplicate"), &AnimationPlayerEditor::_animation_duplicate); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_blend_editor_next_changed"), &AnimationPlayerEditor::_blend_editor_next_changed); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_unhandled_key_input"), &AnimationPlayerEditor::_unhandled_key_input); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_animation_tool_menu"), &AnimationPlayerEditor::_animation_tool_menu); | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("_onion_skinning_menu"), &AnimationPlayerEditor::_onion_skinning_menu); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_editor_visibility_changed"), &AnimationPlayerEditor::_editor_visibility_changed); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_prepare_onion_layers_1"), &AnimationPlayerEditor::_prepare_onion_layers_1); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_prepare_onion_layers_2"), &AnimationPlayerEditor::_prepare_onion_layers_2); | 
					
						
							| 
									
										
										
										
											2019-06-19 00:51:06 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("_start_onion_skinning"), &AnimationPlayerEditor::_start_onion_skinning); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_stop_onion_skinning"), &AnimationPlayerEditor::_stop_onion_skinning); | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_pin_pressed"), &AnimationPlayerEditor::_pin_pressed); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | AnimationPlayerEditor *AnimationPlayerEditor::singleton = NULL; | 
					
						
							| 
									
										
										
										
											2015-12-05 14:18:22 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | AnimationPlayer *AnimationPlayerEditor::get_player() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return player; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlayerEditorPlugin *p_plugin) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	editor = p_editor; | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	plugin = p_plugin; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	singleton = this; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	updating = false; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	set_focus_mode(FOCUS_ALL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	player = NULL; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	HBoxContainer *hb = memnew(HBoxContainer); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	add_child(hb); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	play_bw_from = memnew(ToolButton); | 
					
						
							| 
									
										
										
										
											2016-05-19 00:08:12 +02:00
										 |  |  | 	play_bw_from->set_tooltip(TTR("Play selected animation backwards from current pos. (A)")); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 	hb->add_child(play_bw_from); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	play_bw = memnew(ToolButton); | 
					
						
							| 
									
										
										
										
											2016-05-19 00:08:12 +02:00
										 |  |  | 	play_bw->set_tooltip(TTR("Play selected animation backwards from end. (Shift+A)")); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 	hb->add_child(play_bw); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	stop = memnew(ToolButton); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 	stop->set_toggle_mode(true); | 
					
						
							|  |  |  | 	hb->add_child(stop); | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 	stop->set_tooltip(TTR("Stop animation playback. (S)")); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	play = memnew(ToolButton); | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 	play->set_tooltip(TTR("Play selected animation from start. (Shift+D)")); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 	hb->add_child(play); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	play_from = memnew(ToolButton); | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 	play_from->set_tooltip(TTR("Play selected animation from current pos. (D)")); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 	hb->add_child(play_from); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	frame = memnew(SpinBox); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 	hb->add_child(frame); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	frame->set_custom_minimum_size(Size2(60, 0)); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 	frame->set_stretch_ratio(2); | 
					
						
							| 
									
										
										
										
											2019-08-06 12:24:08 +02:00
										 |  |  | 	frame->set_step(0.0001); | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 	frame->set_tooltip(TTR("Animation position (in seconds).")); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	hb->add_child(memnew(VSeparator)); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	scale = memnew(LineEdit); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 	hb->add_child(scale); | 
					
						
							|  |  |  | 	scale->set_h_size_flags(SIZE_EXPAND_FILL); | 
					
						
							|  |  |  | 	scale->set_stretch_ratio(1); | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 	scale->set_tooltip(TTR("Scale animation playback globally for the node.")); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 	scale->hide(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-19 20:40:24 +01:00
										 |  |  | 	accept = memnew(AcceptDialog); | 
					
						
							|  |  |  | 	add_child(accept); | 
					
						
							|  |  |  | 	accept->connect("confirmed", this, "_menu_confirm_current"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-25 21:22:16 +01:00
										 |  |  | 	delete_dialog = memnew(ConfirmationDialog); | 
					
						
							|  |  |  | 	add_child(delete_dialog); | 
					
						
							|  |  |  | 	delete_dialog->connect("confirmed", this, "_animation_remove_confirmed"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 	tool_anim = memnew(MenuButton); | 
					
						
							|  |  |  | 	tool_anim->set_flat(false); | 
					
						
							|  |  |  | 	tool_anim->set_tooltip(TTR("Animation Tools")); | 
					
						
							| 
									
										
										
										
											2018-06-08 14:44:18 -03:00
										 |  |  | 	tool_anim->set_text(TTR("Animation")); | 
					
						
							|  |  |  | 	tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/new_animation", TTR("New")), TOOL_NEW_ANIM); | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 	tool_anim->get_popup()->add_separator(); | 
					
						
							| 
									
										
										
										
											2018-06-08 14:44:18 -03:00
										 |  |  | 	tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/open_animation", TTR("Load")), TOOL_LOAD_ANIM); | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 	tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/save_animation", TTR("Save")), TOOL_SAVE_ANIM); | 
					
						
							| 
									
										
										
										
											2018-06-08 14:44:18 -03:00
										 |  |  | 	tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/save_as_animation", TTR("Save As...")), TOOL_SAVE_AS_ANIM); | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 	tool_anim->get_popup()->add_separator(); | 
					
						
							|  |  |  | 	tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/copy_animation", TTR("Copy")), TOOL_COPY_ANIM); | 
					
						
							|  |  |  | 	tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/paste_animation", TTR("Paste")), TOOL_PASTE_ANIM); | 
					
						
							|  |  |  | 	tool_anim->get_popup()->add_separator(); | 
					
						
							|  |  |  | 	tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/duplicate_animation", TTR("Duplicate")), TOOL_DUPLICATE_ANIM); | 
					
						
							|  |  |  | 	tool_anim->get_popup()->add_separator(); | 
					
						
							|  |  |  | 	tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/rename_animation", TTR("Rename...")), TOOL_RENAME_ANIM); | 
					
						
							|  |  |  | 	tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/edit_transitions", TTR("Edit Transitions...")), TOOL_EDIT_TRANSITIONS); | 
					
						
							| 
									
										
										
										
											2018-07-01 17:44:15 -03:00
										 |  |  | 	tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/open_animation_in_inspector", TTR("Open in Inspector")), TOOL_EDIT_RESOURCE); | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 	tool_anim->get_popup()->add_separator(); | 
					
						
							|  |  |  | 	tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/remove_animation", TTR("Remove")), TOOL_REMOVE_ANIM); | 
					
						
							|  |  |  | 	hb->add_child(tool_anim); | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	animation = memnew(OptionButton); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	hb->add_child(animation); | 
					
						
							|  |  |  | 	animation->set_h_size_flags(SIZE_EXPAND_FILL); | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 	animation->set_tooltip(TTR("Display list of animations in player.")); | 
					
						
							| 
									
										
										
										
											2016-06-29 20:11:14 -03:00
										 |  |  | 	animation->set_clip_text(true); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	autoplay = memnew(ToolButton); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	hb->add_child(autoplay); | 
					
						
							| 
									
										
										
										
											2016-05-19 00:08:12 +02:00
										 |  |  | 	autoplay->set_tooltip(TTR("Autoplay on Load")); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-09 15:49:16 -03:00
										 |  |  | 	hb->add_child(memnew(VSeparator)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 	track_editor = memnew(AnimationTrackEditor); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hb->add_child(track_editor->get_edit_menu()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-14 00:42:05 -03:00
										 |  |  | 	hb->add_child(memnew(VSeparator)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	onion_toggle = memnew(ToolButton); | 
					
						
							|  |  |  | 	onion_toggle->set_toggle_mode(true); | 
					
						
							|  |  |  | 	onion_toggle->set_tooltip(TTR("Enable Onion Skinning")); | 
					
						
							|  |  |  | 	onion_toggle->connect("pressed", this, "_onion_skinning_menu", varray(ONION_SKINNING_ENABLE)); | 
					
						
							|  |  |  | 	hb->add_child(onion_toggle); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	onion_skinning = memnew(MenuButton); | 
					
						
							| 
									
										
										
										
											2019-05-14 00:42:05 -03:00
										 |  |  | 	onion_skinning->set_tooltip(TTR("Onion Skinning Options")); | 
					
						
							|  |  |  | 	onion_skinning->get_popup()->add_separator(TTR("Directions")); | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	onion_skinning->get_popup()->add_check_item(TTR("Past"), ONION_SKINNING_PAST); | 
					
						
							|  |  |  | 	onion_skinning->get_popup()->set_item_checked(onion_skinning->get_popup()->get_item_count() - 1, true); | 
					
						
							|  |  |  | 	onion_skinning->get_popup()->add_check_item(TTR("Future"), ONION_SKINNING_FUTURE); | 
					
						
							| 
									
										
										
										
											2019-05-14 00:42:05 -03:00
										 |  |  | 	onion_skinning->get_popup()->add_separator(TTR("Depth")); | 
					
						
							| 
									
										
										
										
											2018-03-24 03:05:20 +01:00
										 |  |  | 	onion_skinning->get_popup()->add_radio_check_item(TTR("1 step"), ONION_SKINNING_1_STEP); | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	onion_skinning->get_popup()->set_item_checked(onion_skinning->get_popup()->get_item_count() - 1, true); | 
					
						
							| 
									
										
										
										
											2018-03-24 03:05:20 +01:00
										 |  |  | 	onion_skinning->get_popup()->add_radio_check_item(TTR("2 steps"), ONION_SKINNING_2_STEPS); | 
					
						
							|  |  |  | 	onion_skinning->get_popup()->add_radio_check_item(TTR("3 steps"), ONION_SKINNING_3_STEPS); | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	onion_skinning->get_popup()->add_separator(); | 
					
						
							|  |  |  | 	onion_skinning->get_popup()->add_check_item(TTR("Differences Only"), ONION_SKINNING_DIFFERENCES_ONLY); | 
					
						
							|  |  |  | 	onion_skinning->get_popup()->add_check_item(TTR("Force White Modulate"), ONION_SKINNING_FORCE_WHITE_MODULATE); | 
					
						
							|  |  |  | 	onion_skinning->get_popup()->add_check_item(TTR("Include Gizmos (3D)"), ONION_SKINNING_INCLUDE_GIZMOS); | 
					
						
							|  |  |  | 	hb->add_child(onion_skinning); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-14 00:42:05 -03:00
										 |  |  | 	hb->add_child(memnew(VSeparator)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	pin = memnew(ToolButton); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 	pin->set_toggle_mode(true); | 
					
						
							| 
									
										
										
										
											2018-04-26 22:58:30 -03:00
										 |  |  | 	pin->set_tooltip(TTR("Pin AnimationPlayer")); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 	hb->add_child(pin); | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 	pin->connect("pressed", this, "_pin_pressed"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-06 09:44:38 -03:00
										 |  |  | 	file = memnew(EditorFileDialog); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	add_child(file); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	name_dialog = memnew(ConfirmationDialog); | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 	name_dialog->set_title(TTR("Create New Animation")); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	name_dialog->set_hide_on_ok(false); | 
					
						
							|  |  |  | 	add_child(name_dialog); | 
					
						
							| 
									
										
										
										
											2017-06-13 14:04:15 +08:00
										 |  |  | 	VBoxContainer *vb = memnew(VBoxContainer); | 
					
						
							|  |  |  | 	name_dialog->add_child(vb); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-24 22:47:16 -03:00
										 |  |  | 	name_title = memnew(Label(TTR("Animation Name:"))); | 
					
						
							|  |  |  | 	vb->add_child(name_title); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-13 14:04:15 +08:00
										 |  |  | 	name = memnew(LineEdit); | 
					
						
							|  |  |  | 	vb->add_child(name); | 
					
						
							|  |  |  | 	name_dialog->register_text_enter(name); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	error_dialog = memnew(ConfirmationDialog); | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 	error_dialog->get_ok()->set_text(TTR("Close")); | 
					
						
							| 
									
										
										
										
											2018-04-26 22:58:30 -03:00
										 |  |  | 	error_dialog->set_title(TTR("Error!")); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	add_child(error_dialog); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	name_dialog->connect("confirmed", this, "_animation_name_edited"); | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	blend_editor.dialog = memnew(AcceptDialog); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	add_child(blend_editor.dialog); | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 	blend_editor.dialog->get_ok()->set_text(TTR("Close")); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	blend_editor.dialog->set_hide_on_ok(true); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	VBoxContainer *blend_vb = memnew(VBoxContainer); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	blend_editor.dialog->add_child(blend_vb); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	blend_editor.tree = memnew(Tree); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	blend_editor.tree->set_columns(2); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	blend_vb->add_margin_child(TTR("Blend Times:"), blend_editor.tree, true); | 
					
						
							|  |  |  | 	blend_editor.next = memnew(OptionButton); | 
					
						
							|  |  |  | 	blend_vb->add_margin_child(TTR("Next (Auto Queue):"), blend_editor.next); | 
					
						
							| 
									
										
										
										
											2016-05-03 22:25:37 -03:00
										 |  |  | 	blend_editor.dialog->set_title(TTR("Cross-Animation Blend Times")); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	updating_blends = false; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	blend_editor.tree->connect("item_edited", this, "_blend_edited"); | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	autoplay->connect("pressed", this, "_autoplay_pressed"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	autoplay->set_toggle_mode(true); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	play->connect("pressed", this, "_play_pressed"); | 
					
						
							|  |  |  | 	play_from->connect("pressed", this, "_play_from_pressed"); | 
					
						
							|  |  |  | 	play_bw->connect("pressed", this, "_play_bw_pressed"); | 
					
						
							|  |  |  | 	play_bw_from->connect("pressed", this, "_play_bw_from_pressed"); | 
					
						
							|  |  |  | 	stop->connect("pressed", this, "_stop_pressed"); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	animation->connect("item_selected", this, "_animation_selected", Vector<Variant>(), true); | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	file->connect("file_selected", this, "_dialog_action"); | 
					
						
							|  |  |  | 	frame->connect("value_changed", this, "_seek_value_changed", Vector<Variant>(), true); | 
					
						
							|  |  |  | 	scale->connect("text_entered", this, "_scale_changed", Vector<Variant>(), true); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	renaming = false; | 
					
						
							|  |  |  | 	last_active = false; | 
					
						
							| 
									
										
										
										
											2019-10-01 18:38:03 +02:00
										 |  |  | 	timeline_position = 0; | 
					
						
							| 
									
										
										
										
											2015-05-25 01:46:45 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	set_process_unhandled_key_input(true); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 	add_child(track_editor); | 
					
						
							|  |  |  | 	track_editor->set_v_size_flags(SIZE_EXPAND_FILL); | 
					
						
							|  |  |  | 	track_editor->connect("timeline_changed", this, "_animation_key_editor_seek"); | 
					
						
							| 
									
										
										
										
											2019-05-31 04:43:46 +09:00
										 |  |  | 	track_editor->connect("animation_len_changed", this, "_animation_key_editor_anim_len_changed"); | 
					
						
							| 
									
										
										
										
											2016-01-17 20:03:57 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	_update_player(); | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-04 02:20:57 -03:00
										 |  |  | 	// Onion skinning.
 | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 12:46:14 -03:00
										 |  |  | 	track_editor->connect("visibility_changed", this, "_editor_visibility_changed"); | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	onion.enabled = false; | 
					
						
							|  |  |  | 	onion.past = true; | 
					
						
							|  |  |  | 	onion.future = false; | 
					
						
							|  |  |  | 	onion.steps = 1; | 
					
						
							|  |  |  | 	onion.differences_only = false; | 
					
						
							|  |  |  | 	onion.force_white_modulate = false; | 
					
						
							|  |  |  | 	onion.include_gizmos = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	onion.last_frame = 0; | 
					
						
							|  |  |  | 	onion.can_overlay = false; | 
					
						
							|  |  |  | 	onion.capture_size = Size2(); | 
					
						
							|  |  |  | 	onion.capture.canvas = VS::get_singleton()->canvas_create(); | 
					
						
							|  |  |  | 	onion.capture.canvas_item = VS::get_singleton()->canvas_item_create(); | 
					
						
							|  |  |  | 	VS::get_singleton()->canvas_item_set_parent(onion.capture.canvas_item, onion.capture.canvas); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	onion.capture.material = Ref<ShaderMaterial>(memnew(ShaderMaterial)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	onion.capture.shader = Ref<Shader>(memnew(Shader)); | 
					
						
							|  |  |  | 	onion.capture.shader->set_code(" \
 | 
					
						
							|  |  |  | 		shader_type canvas_item; \ | 
					
						
							|  |  |  | 		\ | 
					
						
							|  |  |  |         uniform vec4 bkg_color; \ | 
					
						
							|  |  |  | 		uniform vec4 dir_color; \ | 
					
						
							|  |  |  | 		uniform bool differences_only; \ | 
					
						
							|  |  |  | 		uniform sampler2D present; \ | 
					
						
							|  |  |  | 		\ | 
					
						
							|  |  |  | 		float zero_if_equal(vec4 a, vec4 b) { \ | 
					
						
							|  |  |  | 			return smoothstep(0.0, 0.005, length(a.rgb - b.rgb) / sqrt(3.0)); \ | 
					
						
							|  |  |  | 		} \ | 
					
						
							|  |  |  | 		\ | 
					
						
							|  |  |  | 		void fragment() { \ | 
					
						
							|  |  |  | 			vec4 capture_samp = texture(TEXTURE, UV); \ | 
					
						
							|  |  |  | 			vec4 present_samp = texture(present, UV); \ | 
					
						
							|  |  |  | 			float bkg_mask = zero_if_equal(capture_samp, bkg_color); \ | 
					
						
							|  |  |  | 			float diff_mask = 1.0 - zero_if_equal(present_samp, bkg_color); \ | 
					
						
							|  |  |  | 			diff_mask = min(1.0, diff_mask + float(!differences_only)); \ | 
					
						
							|  |  |  | 			COLOR = vec4(capture_samp.rgb * dir_color.rgb, bkg_mask * diff_mask); \ | 
					
						
							|  |  |  | 		} \ | 
					
						
							|  |  |  | 	"); | 
					
						
							|  |  |  | 	VS::get_singleton()->material_set_shader(onion.capture.material->get_rid(), onion.capture.shader->get_rid()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AnimationPlayerEditor::~AnimationPlayerEditor() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_free_onion_layers(); | 
					
						
							|  |  |  | 	VS::get_singleton()->free(onion.capture.canvas); | 
					
						
							|  |  |  | 	VS::get_singleton()->free(onion.capture.canvas_item); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditorPlugin::_notification(int p_what) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (p_what) { | 
					
						
							|  |  |  | 		case NOTIFICATION_ENTER_TREE: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			set_force_draw_over_forwarding_enabled(); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditorPlugin::edit(Object *p_object) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	anim_editor->set_undo_redo(&get_undo_redo()); | 
					
						
							|  |  |  | 	if (!p_object) | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2017-08-24 22:58:51 +02:00
										 |  |  | 	anim_editor->edit(Object::cast_to<AnimationPlayer>(p_object)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool AnimationPlayerEditorPlugin::handles(Object *p_object) const { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 	return p_object->is_class("AnimationPlayer"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimationPlayerEditorPlugin::make_visible(bool p_visible) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p_visible) { | 
					
						
							| 
									
										
										
										
											2016-03-15 15:15:50 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		editor->make_bottom_panel_item_visible(anim_editor); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		anim_editor->set_process(true); | 
					
						
							|  |  |  | 		anim_editor->ensure_visibility(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AnimationPlayerEditorPlugin::AnimationPlayerEditorPlugin(EditorNode *p_node) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	editor = p_node; | 
					
						
							| 
									
										
										
										
											2017-10-30 19:43:19 +01:00
										 |  |  | 	anim_editor = memnew(AnimationPlayerEditor(editor, this)); | 
					
						
							| 
									
										
										
										
											2019-06-26 15:08:25 +02:00
										 |  |  | 	anim_editor->set_undo_redo(EditorNode::get_undo_redo()); | 
					
						
							| 
									
										
										
										
											2019-05-27 12:12:51 -03:00
										 |  |  | 	editor->add_bottom_panel_item(TTR("Animation"), anim_editor); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | AnimationPlayerEditorPlugin::~AnimationPlayerEditorPlugin() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } |