summaryrefslogtreecommitdiff
path: root/editor/animation_track_editor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/animation_track_editor.cpp')
-rw-r--r--editor/animation_track_editor.cpp126
1 files changed, 93 insertions, 33 deletions
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 6fce55f8e3..f4e719f552 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,6 +39,7 @@
#include "editor_scale.h"
#include "scene/animation/animation_player.h"
#include "scene/main/window.h"
+#include "scene/scene_string_names.h"
#include "servers/audio/audio_stream.h"
class AnimationTrackKeyEdit : public Object {
@@ -649,7 +650,7 @@ public:
List<StringName> anims;
ap->get_animation_list(&anims);
for (const StringName &E : anims) {
- if (animations != String()) {
+ if (!animations.is_empty()) {
animations += ",";
}
@@ -658,7 +659,7 @@ public:
}
}
- if (animations != String()) {
+ if (!animations.is_empty()) {
animations += ",";
}
animations += "[stop]";
@@ -1331,7 +1332,7 @@ public:
List<StringName> anims;
ap->get_animation_list(&anims);
for (List<StringName>::Element *G = anims.front(); G; G = G->next()) {
- if (animations != String()) {
+ if (!animations.is_empty()) {
animations += ",";
}
@@ -1340,7 +1341,7 @@ public:
}
}
- if (animations != String()) {
+ if (!animations.is_empty()) {
animations += ",";
}
animations += "[stop]";
@@ -1621,7 +1622,7 @@ void AnimationTimelineEdit::_notification(int p_what) {
if (frame != prev_frame && i >= prev_frame_ofs) {
draw_line(Point2(get_name_limit() + i, 0), Point2(get_name_limit() + i, h), linecolor, Math::round(EDSCALE));
- draw_string(font, Point2(get_name_limit() + i + 3 * EDSCALE, (h - font->get_height(font_size)) / 2 + font->get_ascent(font_size)).floor(), itos(frame), HALIGN_LEFT, zoomw - i, font_size, sub ? color_time_dec : color_time_sec);
+ draw_string(font, Point2(get_name_limit() + i + 3 * EDSCALE, (h - font->get_height(font_size)) / 2 + font->get_ascent(font_size)).floor(), itos(frame), HORIZONTAL_ALIGNMENT_LEFT, zoomw - i, font_size, sub ? color_time_dec : color_time_sec);
prev_frame_ofs = i + font->get_string_size(itos(frame), font_size).x + 5 * EDSCALE;
}
}
@@ -1639,7 +1640,7 @@ void AnimationTimelineEdit::_notification(int p_what) {
if ((sc / step) != (prev_sc / step) || (prev_sc < 0 && sc >= 0)) {
int scd = sc < 0 ? prev_sc : sc;
draw_line(Point2(get_name_limit() + i, 0), Point2(get_name_limit() + i, h), linecolor, Math::round(EDSCALE));
- draw_string(font, Point2(get_name_limit() + i + 3, (h - font->get_height(font_size)) / 2 + font->get_ascent(font_size)).floor(), String::num((scd - (scd % step)) / double(SC_ADJ), decimals), HALIGN_LEFT, zoomw - i, font_size, sub ? color_time_dec : color_time_sec);
+ draw_string(font, Point2(get_name_limit() + i + 3, (h - font->get_height(font_size)) / 2 + font->get_ascent(font_size)).floor(), String::num((scd - (scd % step)) / double(SC_ADJ), decimals), HORIZONTAL_ALIGNMENT_LEFT, zoomw - i, font_size, sub ? color_time_dec : color_time_sec);
}
}
}
@@ -2028,7 +2029,7 @@ void AnimationTrackEdit::_notification(int p_what) {
Vector2 string_pos = Point2(ofs, (get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size));
string_pos = string_pos.floor();
- draw_string(font, string_pos, text, HALIGN_LEFT, limit - ofs - hsep, font_size, text_color);
+ draw_string(font, string_pos, text, HORIZONTAL_ALIGNMENT_LEFT, limit - ofs - hsep, font_size, text_color);
draw_line(Point2(limit, 0), Point2(limit, get_size().height), linecolor, Math::round(EDSCALE));
}
@@ -2339,7 +2340,7 @@ void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool
int limit = MAX(0, p_clip_right - p_x - icon_to_draw->get_width());
if (limit > 0) {
- draw_string(font, Vector2(p_x + icon_to_draw->get_width(), int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), text, HALIGN_LEFT, limit, font_size, color);
+ draw_string(font, Vector2(p_x + icon_to_draw->get_width(), int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), text, HORIZONTAL_ALIGNMENT_LEFT, limit, font_size, color);
}
}
@@ -2664,7 +2665,7 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
if (stream.is_valid()) {
if (stream->get_path().is_resource_file()) {
stream_name = stream->get_path().get_file();
- } else if (stream->get_name() != "") {
+ } else if (!stream->get_name().is_empty()) {
stream_name = stream->get_name();
} else {
stream_name = stream->get_class();
@@ -2872,13 +2873,18 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
if (editor->is_selection_active()) {
menu->add_separator();
menu->add_icon_item(get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons")), TTR("Duplicate Key(s)"), MENU_KEY_DUPLICATE);
+
+ AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
+ if (!player->has_animation(SceneStringNames::get_singleton()->RESET) || animation != player->get_animation(SceneStringNames::get_singleton()->RESET)) {
+ menu->add_icon_item(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")), TTR("Add RESET Value(s)"), MENU_KEY_ADD_RESET);
+ }
+
menu->add_separator();
menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete Key(s)"), MENU_KEY_DELETE);
}
menu->set_as_minsize();
- Vector2 popup_pos = get_screen_transform().xform(get_local_mouse_position());
- menu->set_position(popup_pos);
+ menu->set_position(get_screen_position() + get_local_mouse_position());
menu->popup();
insert_at_pos = offset + timeline->get_value();
@@ -3061,6 +3067,9 @@ void AnimationTrackEdit::_menu_selected(int p_index) {
} break;
case MENU_KEY_DUPLICATE: {
emit_signal(SNAME("duplicate_request"));
+ } break;
+ case MENU_KEY_ADD_RESET: {
+ emit_signal(SNAME("create_reset_request"));
} break;
case MENU_KEY_DELETE: {
@@ -3123,6 +3132,7 @@ void AnimationTrackEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("move_selection_cancel"));
ADD_SIGNAL(MethodInfo("duplicate_request"));
+ ADD_SIGNAL(MethodInfo("create_reset_request"));
ADD_SIGNAL(MethodInfo("duplicate_transpose_request"));
ADD_SIGNAL(MethodInfo("delete_request"));
}
@@ -3224,7 +3234,7 @@ void AnimationTrackEditGroup::_notification(int p_what) {
int ofs = 0;
draw_texture(icon, Point2(ofs, int(get_size().height - icon->get_height()) / 2));
ofs += separation + icon->get_width();
- draw_string(font, Point2(ofs, int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), node_name, HALIGN_LEFT, timeline->get_name_limit() - ofs, font_size, color);
+ draw_string(font, Point2(ofs, int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), node_name, HORIZONTAL_ALIGNMENT_LEFT, timeline->get_name_limit() - ofs, font_size, color);
int px = (-timeline->get_value() + timeline->get_play_position()) * timeline->get_zoom_scale() + timeline->get_name_limit();
@@ -3240,7 +3250,7 @@ void AnimationTrackEditGroup::set_type_and_name(const Ref<Texture2D> &p_type, co
node_name = p_name;
node = p_node;
update();
- minimum_size_changed();
+ update_minimum_size();
}
Size2 AnimationTrackEditGroup::get_minimum_size() const {
@@ -3380,7 +3390,7 @@ Dictionary AnimationTrackEditor::get_state() const {
state["fps_mode"] = timeline->is_using_fps();
state["zoom"] = zoom->get_value();
state["offset"] = timeline->get_value();
- state["v_scroll"] = scroll->get_v_scrollbar()->get_value();
+ state["v_scroll"] = scroll->get_v_scroll_bar()->get_value();
return state;
}
@@ -3408,9 +3418,9 @@ void AnimationTrackEditor::set_state(const Dictionary &p_state) {
timeline->set_value(0);
}
if (p_state.has("v_scroll")) {
- scroll->get_v_scrollbar()->set_value(p_state["v_scroll"]);
+ scroll->get_v_scroll_bar()->set_value(p_state["v_scroll"]);
} else {
- scroll->get_v_scrollbar()->set_value(0);
+ scroll->get_v_scroll_bar()->set_value(0);
}
}
@@ -3505,7 +3515,7 @@ void AnimationTrackEditor::make_insert_queue() {
void AnimationTrackEditor::commit_insert_queue() {
bool reset_allowed = true;
AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
- if (player->has_animation("RESET") && player->get_animation("RESET") == animation) {
+ if (player->has_animation(SceneStringNames::get_singleton()->RESET) && player->get_animation(SceneStringNames::get_singleton()->RESET) == animation) {
// Avoid messing with the reset animation itself.
reset_allowed = false;
} else {
@@ -3647,7 +3657,7 @@ void AnimationTrackEditor::insert_transform_key(Node3D *p_node, const String &p_
// Let's build a node path.
String path = root->get_path_to(p_node);
- if (p_sub != "") {
+ if (!p_sub.is_empty()) {
path += ":" + p_sub;
}
@@ -3687,7 +3697,7 @@ bool AnimationTrackEditor::has_track(Node3D *p_node, const String &p_sub, const
// Let's build a node path.
String path = root->get_path_to(p_node);
- if (p_sub != "") {
+ if (!p_sub.is_empty()) {
path += ":" + p_sub;
}
@@ -3752,7 +3762,7 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
EditorHistory *history = EditorNode::get_singleton()->get_editor_history();
for (int i = 1; i < history->get_path_size(); i++) {
String prop = history->get_path_property(i);
- ERR_FAIL_COND(prop == "");
+ ERR_FAIL_COND(prop.is_empty());
path += ":" + prop;
}
@@ -3852,7 +3862,7 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
for (int i = 1; i < history->get_path_size(); i++) {
String prop = history->get_path_property(i);
- ERR_FAIL_COND(prop == "");
+ ERR_FAIL_COND(prop.is_empty());
path += ":" + prop;
}
@@ -3925,15 +3935,15 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
Ref<Animation> AnimationTrackEditor::_create_and_get_reset_animation() {
AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
- if (player->has_animation("RESET")) {
- return player->get_animation("RESET");
+ if (player->has_animation(SceneStringNames::get_singleton()->RESET)) {
+ return player->get_animation(SceneStringNames::get_singleton()->RESET);
} else {
Ref<Animation> reset_anim;
reset_anim.instantiate();
reset_anim->set_length(ANIM_MIN_LENGTH);
- undo_redo->add_do_method(player, "add_animation", "RESET", reset_anim);
+ undo_redo->add_do_method(player, "add_animation", SceneStringNames::get_singleton()->RESET, reset_anim);
undo_redo->add_do_method(AnimationPlayerEditor::get_singleton(), "_animation_player_changed", player);
- undo_redo->add_undo_method(player, "remove_animation", "RESET");
+ undo_redo->add_undo_method(player, "remove_animation", SceneStringNames::get_singleton()->RESET);
undo_redo->add_undo_method(AnimationPlayerEditor::get_singleton(), "_animation_player_changed", player);
return reset_anim;
}
@@ -4388,6 +4398,7 @@ void AnimationTrackEditor::_update_tracks() {
track_edit->connect("duplicate_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_DUPLICATE_SELECTION), CONNECT_DEFERRED);
track_edit->connect("duplicate_transpose_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_DUPLICATE_TRANSPOSED), CONNECT_DEFERRED);
+ track_edit->connect("create_reset_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_ADD_RESET_KEY), CONNECT_DEFERRED);
track_edit->connect("delete_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_DELETE_SELECTION), CONNECT_DEFERRED);
}
}
@@ -5720,6 +5731,55 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
}
_anim_duplicate_keys(true);
} break;
+ case EDIT_ADD_RESET_KEY: {
+ undo_redo->create_action(TTR("Anim Add RESET Keys"));
+ Ref<Animation> reset = _create_and_get_reset_animation();
+ int reset_tracks = reset->get_track_count();
+ Set<int> tracks_added;
+
+ for (const KeyValue<SelectedKey, KeyInfo> &E : selection) {
+ const SelectedKey &sk = E.key;
+
+ // Only add one key per track.
+ if (tracks_added.has(sk.track)) {
+ continue;
+ }
+ tracks_added.insert(sk.track);
+
+ int dst_track = -1;
+
+ const NodePath &path = animation->track_get_path(sk.track);
+ for (int i = 0; i < reset->get_track_count(); i++) {
+ if (reset->track_get_path(i) == path) {
+ dst_track = i;
+ break;
+ }
+ }
+
+ int existing_idx = -1;
+ if (dst_track == -1) {
+ // If adding multiple tracks, make sure that correct track is referenced.
+ dst_track = reset_tracks;
+ reset_tracks++;
+
+ undo_redo->add_do_method(reset.ptr(), "add_track", animation->track_get_type(sk.track));
+ undo_redo->add_do_method(reset.ptr(), "track_set_path", dst_track, path);
+ undo_redo->add_undo_method(reset.ptr(), "remove_track", dst_track);
+ } else {
+ existing_idx = reset->track_find_key(dst_track, 0, true);
+ }
+
+ undo_redo->add_do_method(reset.ptr(), "track_insert_key", dst_track, 0, animation->track_get_key_value(sk.track, sk.key), animation->track_get_key_transition(sk.track, sk.key));
+ undo_redo->add_undo_method(reset.ptr(), "track_remove_key_at_time", dst_track, 0);
+
+ if (existing_idx != -1) {
+ undo_redo->add_undo_method(reset.ptr(), "track_insert_key", dst_track, 0, reset->track_get_key_value(dst_track, existing_idx), reset->track_get_key_transition(dst_track, existing_idx));
+ }
+ }
+
+ undo_redo->commit_action();
+
+ } break;
case EDIT_DELETE_SELECTION: {
if (bezier_edit->is_visible()) {
bezier_edit->delete_selection();
@@ -5961,7 +6021,7 @@ void AnimationTrackEditor::_pick_track_select_recursive(TreeItem *p_item, const
NodePath np = p_item->get_metadata(0);
Node *node = get_node(np);
- if (p_filter != String() && ((String)node->get_name()).findn(p_filter) != -1) {
+ if (!p_filter.is_empty() && ((String)node->get_name()).findn(p_filter) != -1) {
p_select_candidates.push_back(node);
}
@@ -6012,8 +6072,8 @@ AnimationTrackEditor::AnimationTrackEditor() {
info_message = memnew(Label);
info_message->set_text(TTR("Select an AnimationPlayer node to create and edit animations."));
- info_message->set_valign(Label::VALIGN_CENTER);
- info_message->set_align(Label::ALIGN_CENTER);
+ info_message->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
+ info_message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
info_message->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
info_message->set_anchors_and_offsets_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
@@ -6031,7 +6091,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
scroll = memnew(ScrollContainer);
timeline_vbox->add_child(scroll);
scroll->set_v_size_flags(SIZE_EXPAND_FILL);
- VScrollBar *sb = scroll->get_v_scrollbar();
+ VScrollBar *sb = scroll->get_v_scroll_bar();
scroll->remove_child(sb);
timeline_scroll->add_child(sb); // Move here so timeline and tracks are always aligned.
scroll->connect("gui_input", callable_mp(this, &AnimationTrackEditor::_scroll_input));
@@ -6057,8 +6117,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
track_vbox = memnew(VBoxContainer);
scroll->add_child(track_vbox);
track_vbox->set_h_size_flags(SIZE_EXPAND_FILL);
- scroll->set_enable_h_scroll(false);
- scroll->set_enable_v_scroll(true);
+ scroll->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
track_vbox->add_theme_constant_override("separation", 0);
HBoxContainer *bottom_hb = memnew(HBoxContainer);
@@ -6144,6 +6203,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
edit->get_popup()->add_separator();
edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/duplicate_selection", TTR("Duplicate Selection"), KeyModifierMask::CMD | Key::D), EDIT_DUPLICATE_SELECTION);
edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/duplicate_selection_transposed", TTR("Duplicate Transposed"), KeyModifierMask::SHIFT | KeyModifierMask::CMD | Key::D), EDIT_DUPLICATE_TRANSPOSED);
+ edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/add_reset_value", TTR("Add RESET Value(s)")));
edit->get_popup()->add_separator();
edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/delete_selection", TTR("Delete Selection"), Key::KEY_DELETE), EDIT_DELETE_SELECTION);