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.cpp264
1 files changed, 179 insertions, 85 deletions
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 53631c1e3b..7d8197bead 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -358,7 +358,7 @@ public:
setting = true;
undo_redo->create_action(TTR("Anim Change Keyframe Value"), UndoRedo::MERGE_ENDS);
- RES prev = animation->audio_track_get_key_stream(track, key);
+ Ref<Resource> prev = animation->audio_track_get_key_stream(track, key);
undo_redo->add_do_method(animation.ptr(), "audio_track_set_key_stream", track, key, stream);
undo_redo->add_undo_method(animation.ptr(), "audio_track_set_key_stream", track, key, prev);
undo_redo->add_do_method(this, "_update_obj", animation);
@@ -586,20 +586,20 @@ public:
pi.name = "value";
p_list->push_back(pi);
} else {
- PropertyHint hint = PROPERTY_HINT_NONE;
- String hint_string;
+ PropertyHint val_hint = PROPERTY_HINT_NONE;
+ String val_hint_string;
if (v.get_type() == Variant::OBJECT) {
// Could actually check the object property if exists..? Yes I will!
Ref<Resource> res = v;
if (res.is_valid()) {
- hint = PROPERTY_HINT_RESOURCE_TYPE;
- hint_string = res->get_class();
+ val_hint = PROPERTY_HINT_RESOURCE_TYPE;
+ val_hint_string = res->get_class();
}
}
if (v.get_type() != Variant::NIL) {
- p_list->push_back(PropertyInfo(v.get_type(), "value", hint, hint_string));
+ p_list->push_back(PropertyInfo(v.get_type(), "value", val_hint, val_hint_string));
}
}
@@ -992,7 +992,7 @@ public:
setting = true;
undo_redo->create_action(TTR("Anim Multi Change Keyframe Value"), UndoRedo::MERGE_ENDS);
}
- RES prev = animation->audio_track_get_key_stream(track, key);
+ Ref<Resource> prev = animation->audio_track_get_key_stream(track, key);
undo_redo->add_do_method(animation.ptr(), "audio_track_set_key_stream", track, key, stream);
undo_redo->add_undo_method(animation.ptr(), "audio_track_set_key_stream", track, key, prev);
update_obj = true;
@@ -1264,20 +1264,20 @@ public:
pi.name = "value";
p_list->push_back(pi);
} else {
- PropertyHint hint = PROPERTY_HINT_NONE;
- String hint_string;
+ PropertyHint val_hint = PROPERTY_HINT_NONE;
+ String val_hint_string;
if (v.get_type() == Variant::OBJECT) {
// Could actually check the object property if exists..? Yes I will!
Ref<Resource> res = v;
if (res.is_valid()) {
- hint = PROPERTY_HINT_RESOURCE_TYPE;
- hint_string = res->get_class();
+ val_hint = PROPERTY_HINT_RESOURCE_TYPE;
+ val_hint_string = res->get_class();
}
}
if (v.get_type() != Variant::NIL) {
- p_list->push_back(PropertyInfo(v.get_type(), "value", hint, hint_string));
+ p_list->push_back(PropertyInfo(v.get_type(), "value", val_hint, val_hint_string));
}
}
}
@@ -1353,8 +1353,8 @@ public:
Ref<Animation> animation;
- Map<int, List<float>> key_ofs_map;
- Map<int, NodePath> base_map;
+ RBMap<int, List<float>> key_ofs_map;
+ RBMap<int, NodePath> base_map;
PropertyInfo hint;
Node *root_path = nullptr;
@@ -1572,7 +1572,6 @@ void AnimationTimelineEdit::_notification(int p_what) {
Color color_time_dec = color;
color_time_dec.a *= 0.5;
#define SC_ADJ 100
- int min = 30;
int dec = 1;
int step = 1;
int decimals = 2;
@@ -1588,7 +1587,7 @@ void AnimationTimelineEdit::_notification(int p_what) {
const int max_sc_width = String::num(max_sc).length() * max_digit_width;
while (!step_found) {
- min = max_sc_width;
+ int min = max_sc_width;
if (decimals > 0) {
min += period_width + max_digit_width * decimals;
}
@@ -1887,10 +1886,7 @@ void AnimationTimelineEdit::_bind_methods() {
AnimationTimelineEdit::AnimationTimelineEdit() {
name_limit = 150 * EDSCALE;
- zoom = nullptr;
- track_edit = nullptr;
- play_position_pos = 0;
play_position = memnew(Control);
play_position->set_mouse_filter(MOUSE_FILTER_PASS);
add_child(play_position);
@@ -1981,7 +1977,7 @@ void AnimationTrackEdit::_notification(int p_what) {
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
Color color = get_theme_color(SNAME("font_color"), SNAME("Label"));
- int hsep = get_theme_constant(SNAME("hseparation"), SNAME("ItemList"));
+ int hsep = get_theme_constant(SNAME("h_separation"), SNAME("ItemList"));
Color linecolor = color;
linecolor.a = 0.2;
@@ -2252,6 +2248,8 @@ void AnimationTrackEdit::_notification(int p_what) {
break;
case NOTIFICATION_MOUSE_EXIT:
hovered = false;
+ // When the mouse cursor exits the track, we're no longer hovering any keyframe.
+ hovering_key_idx = -1;
update();
[[fallthrough]];
case NOTIFICATION_DRAG_END: {
@@ -2365,7 +2363,13 @@ void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool
}
}
- draw_texture(icon_to_draw, ofs);
+ // Use a different color for the currently hovered key.
+ // The color multiplier is chosen to work with both dark and light editor themes,
+ // and on both unselected and selected key icons.
+ draw_texture(
+ icon_to_draw,
+ ofs,
+ p_index == hovering_key_idx ? get_theme_color(SNAME("folder_icon_modulate"), SNAME("FileDialog")) : Color(1, 1, 1));
}
// Helper.
@@ -2454,7 +2458,7 @@ Size2 AnimationTrackEdit::get_minimum_size() const {
Ref<Texture2D> texture = get_theme_icon(SNAME("Object"), SNAME("EditorIcons"));
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
- int separation = get_theme_constant(SNAME("vseparation"), SNAME("ItemList"));
+ int separation = get_theme_constant(SNAME("v_separation"), SNAME("ItemList"));
int max_h = MAX(texture->get_height(), font->get_height(font_size));
max_h = MAX(max_h, get_key_height());
@@ -2524,7 +2528,7 @@ bool AnimationTrackEdit::_is_value_key_valid(const Variant &p_key_value, Variant
return false;
}
- RES res;
+ Ref<Resource> res;
Vector<StringName> leftover_path;
Node *node = root->get_node_and_resource(animation->track_get_path(track), res, leftover_path);
@@ -2544,7 +2548,7 @@ bool AnimationTrackEdit::_is_value_key_valid(const Variant &p_key_value, Variant
}
Ref<Texture2D> AnimationTrackEdit::_get_key_type_icon() const {
- Ref<Texture2D> type_icons[9] = {
+ const Ref<Texture2D> type_icons[9] = {
get_theme_icon(SNAME("KeyValue"), SNAME("EditorIcons")),
get_theme_icon(SNAME("KeyTrackPosition"), SNAME("EditorIcons")),
get_theme_icon(SNAME("KeyTrackRotation"), SNAME("EditorIcons")),
@@ -2685,7 +2689,7 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
} break;
case Animation::TYPE_AUDIO: {
String stream_name = "null";
- RES stream = animation->audio_track_get_key_stream(track, key_idx);
+ Ref<Resource> stream = animation->audio_track_get_key_stream(track, key_idx);
if (stream.is_valid()) {
if (stream->get_path().is_resource_file()) {
stream_name = stream->get_path().get_file();
@@ -2952,6 +2956,59 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
}
Ref<InputEventMouseMotion> mm = p_event;
+ if (mm.is_valid()) {
+ const int previous_hovering_key_idx = hovering_key_idx;
+
+ // Hovering compressed keyframes for editing is not possible.
+ if (!animation->track_is_compressed(track)) {
+ const float scale = timeline->get_zoom_scale();
+ const int limit = timeline->get_name_limit();
+ const int limit_end = get_size().width - timeline->get_buttons_width();
+ // Left Border including space occupied by keyframes on t=0.
+ const int limit_start_hitbox = limit - type_icon->get_width();
+ const Point2 pos = mm->get_position();
+
+ if (pos.x >= limit_start_hitbox && pos.x <= limit_end) {
+ // Use the same logic as key selection to ensure that hovering accurately represents
+ // which key will be selected when clicking.
+ int key_idx = -1;
+ float key_distance = 1e20;
+
+ hovering_key_idx = -1;
+
+ // Hovering should happen in the opposite order of drawing for more accurate overlap hovering.
+ for (int i = animation->track_get_key_count(track) - 1; i >= 0; i--) {
+ Rect2 rect = get_key_rect(i, scale);
+ float offset = animation->track_get_key_time(track, i) - timeline->get_value();
+ offset = offset * scale + limit;
+ rect.position.x += offset;
+
+ if (rect.has_point(pos)) {
+ if (is_key_selectable_by_distance()) {
+ const float distance = ABS(offset - pos.x);
+ if (key_idx == -1 || distance < key_distance) {
+ key_idx = i;
+ key_distance = distance;
+ hovering_key_idx = i;
+ }
+ } else {
+ // First one does it.
+ hovering_key_idx = i;
+ break;
+ }
+ }
+ }
+
+ print_line(hovering_key_idx);
+
+ if (hovering_key_idx != previous_hovering_key_idx) {
+ // Required to draw keyframe hover feedback on the correct keyframe.
+ update();
+ }
+ }
+ }
+ }
+
if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE && moving_selection_attempt) {
if (!moving_selection) {
moving_selection = true;
@@ -3140,13 +3197,13 @@ void AnimationTrackEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("timeline_changed", PropertyInfo(Variant::FLOAT, "position"), PropertyInfo(Variant::BOOL, "drag"), PropertyInfo(Variant::BOOL, "timeline_only")));
ADD_SIGNAL(MethodInfo("remove_request", PropertyInfo(Variant::INT, "track")));
ADD_SIGNAL(MethodInfo("dropped", PropertyInfo(Variant::INT, "from_track"), PropertyInfo(Variant::INT, "to_track")));
- ADD_SIGNAL(MethodInfo("insert_key", PropertyInfo(Variant::FLOAT, "ofs")));
+ ADD_SIGNAL(MethodInfo("insert_key", PropertyInfo(Variant::FLOAT, "offset")));
ADD_SIGNAL(MethodInfo("select_key", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::BOOL, "single")));
ADD_SIGNAL(MethodInfo("deselect_key", PropertyInfo(Variant::INT, "index")));
ADD_SIGNAL(MethodInfo("bezier_edit"));
ADD_SIGNAL(MethodInfo("move_selection_begin"));
- ADD_SIGNAL(MethodInfo("move_selection", PropertyInfo(Variant::FLOAT, "ofs")));
+ ADD_SIGNAL(MethodInfo("move_selection", PropertyInfo(Variant::FLOAT, "offset")));
ADD_SIGNAL(MethodInfo("move_selection_commit"));
ADD_SIGNAL(MethodInfo("move_selection_cancel"));
@@ -3157,17 +3214,6 @@ void AnimationTrackEdit::_bind_methods() {
}
AnimationTrackEdit::AnimationTrackEdit() {
- undo_redo = nullptr;
- timeline = nullptr;
- root = nullptr;
- path = nullptr;
- path_popup = nullptr;
- menu = nullptr;
- dropping_at = 0;
-
- select_single_attempt = -1;
-
- play_position_pos = 0;
play_position = memnew(Control);
play_position->set_mouse_filter(MOUSE_FILTER_PASS);
add_child(play_position);
@@ -3226,7 +3272,7 @@ void AnimationTrackEditGroup::_notification(int p_what) {
case NOTIFICATION_DRAW: {
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
- int separation = get_theme_constant(SNAME("hseparation"), SNAME("ItemList"));
+ int separation = get_theme_constant(SNAME("h_separation"), SNAME("ItemList"));
Color color = get_theme_color(SNAME("font_color"), SNAME("Label"));
if (root && root->has_node(node)) {
@@ -3272,7 +3318,7 @@ void AnimationTrackEditGroup::set_type_and_name(const Ref<Texture2D> &p_type, co
Size2 AnimationTrackEditGroup::get_minimum_size() const {
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
- int separation = get_theme_constant(SNAME("vseparation"), SNAME("ItemList"));
+ int separation = get_theme_constant(SNAME("v_separation"), SNAME("ItemList"));
return Vector2(0, MAX(font->get_height(font_size), icon->get_height()) + separation);
}
@@ -3375,7 +3421,7 @@ Ref<Animation> AnimationTrackEditor::get_current_animation() const {
return animation;
}
-void AnimationTrackEditor::_root_removed(Node *p_root) {
+void AnimationTrackEditor::_root_removed() {
root = nullptr;
}
@@ -3473,31 +3519,75 @@ void AnimationTrackEditor::_timeline_changed(float p_new_pos, bool p_drag, bool
}
void AnimationTrackEditor::_track_remove_request(int p_track) {
- if (animation->track_is_compressed(p_track)) {
+ _animation_track_remove_request(p_track, animation);
+}
+
+void AnimationTrackEditor::_animation_track_remove_request(int p_track, Ref<Animation> p_from_animation) {
+ if (p_from_animation->track_is_compressed(p_track)) {
EditorNode::get_singleton()->show_warning(TTR("Compressed tracks can't be edited or removed. Re-import the animation with compression disabled in order to edit."));
return;
}
int idx = p_track;
- if (idx >= 0 && idx < animation->get_track_count()) {
+ if (idx >= 0 && idx < p_from_animation->get_track_count()) {
undo_redo->create_action(TTR("Remove Anim Track"));
+
+ // Remove corresponding reset tracks if they are no longer needed.
+ AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
+ if (player->has_animation(SceneStringNames::get_singleton()->RESET)) {
+ Ref<Animation> reset = player->get_animation(SceneStringNames::get_singleton()->RESET);
+ if (reset != p_from_animation) {
+ for (int i = 0; i < reset->get_track_count(); i++) {
+ if (reset->track_get_path(i) == p_from_animation->track_get_path(p_track)) {
+ // Check if the reset track isn't used by other animations.
+ bool used = false;
+ List<StringName> animation_list;
+ player->get_animation_list(&animation_list);
+
+ for (const StringName &anim_name : animation_list) {
+ Ref<Animation> anim = player->get_animation(anim_name);
+ if (anim == p_from_animation || anim == reset) {
+ continue;
+ }
+
+ for (int j = 0; j < anim->get_track_count(); j++) {
+ if (anim->track_get_path(j) == reset->track_get_path(i)) {
+ used = true;
+ break;
+ }
+ }
+
+ if (used) {
+ break;
+ }
+ }
+
+ if (!used) {
+ _animation_track_remove_request(i, reset);
+ }
+ break;
+ }
+ }
+ }
+ }
+
undo_redo->add_do_method(this, "_clear_selection", false);
- undo_redo->add_do_method(animation.ptr(), "remove_track", idx);
- undo_redo->add_undo_method(animation.ptr(), "add_track", animation->track_get_type(idx), idx);
- undo_redo->add_undo_method(animation.ptr(), "track_set_path", idx, animation->track_get_path(idx));
+ undo_redo->add_do_method(p_from_animation.ptr(), "remove_track", idx);
+ undo_redo->add_undo_method(p_from_animation.ptr(), "add_track", p_from_animation->track_get_type(idx), idx);
+ undo_redo->add_undo_method(p_from_animation.ptr(), "track_set_path", idx, p_from_animation->track_get_path(idx));
// TODO interpolation.
- for (int i = 0; i < animation->track_get_key_count(idx); i++) {
- Variant v = animation->track_get_key_value(idx, i);
- float time = animation->track_get_key_time(idx, i);
- float trans = animation->track_get_key_transition(idx, i);
+ for (int i = 0; i < p_from_animation->track_get_key_count(idx); i++) {
+ Variant v = p_from_animation->track_get_key_value(idx, i);
+ float time = p_from_animation->track_get_key_time(idx, i);
+ float trans = p_from_animation->track_get_key_transition(idx, i);
- undo_redo->add_undo_method(animation.ptr(), "track_insert_key", idx, time, v);
- undo_redo->add_undo_method(animation.ptr(), "track_set_key_transition", idx, i, trans);
+ undo_redo->add_undo_method(p_from_animation.ptr(), "track_insert_key", idx, time, v);
+ undo_redo->add_undo_method(p_from_animation.ptr(), "track_set_key_transition", idx, i, trans);
}
- undo_redo->add_undo_method(animation.ptr(), "track_set_interpolation_type", idx, animation->track_get_interpolation_type(idx));
- if (animation->track_get_type(idx) == Animation::TYPE_VALUE) {
- undo_redo->add_undo_method(animation.ptr(), "value_track_set_update_mode", idx, animation->value_track_get_update_mode(idx));
+ undo_redo->add_undo_method(p_from_animation.ptr(), "track_set_interpolation_type", idx, p_from_animation->track_get_interpolation_type(idx));
+ if (p_from_animation->track_get_type(idx) == Animation::TYPE_VALUE) {
+ undo_redo->add_undo_method(p_from_animation.ptr(), "value_track_set_update_mode", idx, p_from_animation->value_track_get_update_mode(idx));
}
undo_redo->commit_action();
@@ -3972,12 +4062,20 @@ Ref<Animation> AnimationTrackEditor::_create_and_get_reset_animation() {
if (player->has_animation(SceneStringNames::get_singleton()->RESET)) {
return player->get_animation(SceneStringNames::get_singleton()->RESET);
} else {
+ Ref<AnimationLibrary> al;
+ if (!player->has_animation_library("")) {
+ al.instantiate();
+ player->add_animation_library("", al);
+ } else {
+ al = player->get_animation_library("");
+ }
+
Ref<Animation> reset_anim;
reset_anim.instantiate();
reset_anim->set_length(ANIM_MIN_LENGTH);
- undo_redo->add_do_method(player, "add_animation", SceneStringNames::get_singleton()->RESET, reset_anim);
+ undo_redo->add_do_method(al.ptr(), "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", SceneStringNames::get_singleton()->RESET);
+ undo_redo->add_undo_method(al.ptr(), "remove_animation", SceneStringNames::get_singleton()->RESET);
undo_redo->add_undo_method(AnimationPlayerEditor::get_singleton(), "_animation_player_changed", player);
return reset_anim;
}
@@ -4016,7 +4114,7 @@ PropertyInfo AnimationTrackEditor::_find_hint_for_track(int p_idx, NodePath &r_b
return PropertyInfo();
}
- RES res;
+ Ref<Resource> res;
Vector<StringName> leftover_path;
Node *node = root->get_node_and_resource(path, res, leftover_path, true);
@@ -4284,7 +4382,7 @@ void AnimationTrackEditor::_update_tracks() {
return;
}
- Map<String, VBoxContainer *> group_sort;
+ RBMap<String, VBoxContainer *> group_sort;
bool use_grouping = !view_group->is_pressed();
bool use_filter = selected_filter->is_pressed();
@@ -4312,7 +4410,7 @@ void AnimationTrackEditor::_update_tracks() {
NodePath path = animation->track_get_path(i);
if (root && root->has_node_and_resource(path)) {
- RES res;
+ Ref<Resource> res;
NodePath base_path;
Vector<StringName> leftover_path;
Node *node = root->get_node_and_resource(path, res, leftover_path, true);
@@ -4918,7 +5016,7 @@ void AnimationTrackEditor::_insert_key_from_track(float p_ofs, int p_track) {
} break;
case Animation::TYPE_AUDIO: {
Dictionary ak;
- ak["stream"] = RES();
+ ak["stream"] = Ref<Resource>();
ak["start_offset"] = 0;
ak["end_offset"] = 0;
@@ -5101,8 +5199,8 @@ void AnimationTrackEditor::_update_key_edit() {
multi_key_edit = memnew(AnimationMultiTrackKeyEdit);
multi_key_edit->animation = animation;
- Map<int, List<float>> key_ofs_map;
- Map<int, NodePath> base_map;
+ RBMap<int, List<float>> key_ofs_map;
+ RBMap<int, NodePath> base_map;
int first_track = -1;
for (const KeyValue<SelectedKey, KeyInfo> &E : selection) {
int track = E.key.track;
@@ -5163,11 +5261,11 @@ void AnimationTrackEditor::_move_selection_commit() {
float motion = moving_selection_offset;
// 1 - remove the keys.
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
undo_redo->add_do_method(animation.ptr(), "track_remove_key", E->key().track, E->key().key);
}
// 2 - Remove overlapped keys.
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
float newtime = snap_time(E->get().pos + motion);
int idx = animation->track_find_key(E->key().track, newtime, true);
if (idx == -1) {
@@ -5192,19 +5290,19 @@ void AnimationTrackEditor::_move_selection_commit() {
}
// 3 - Move the keys (Reinsert them).
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
float newpos = snap_time(E->get().pos + motion);
undo_redo->add_do_method(animation.ptr(), "track_insert_key", E->key().track, newpos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
}
// 4 - (Undo) Remove inserted keys.
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
float newpos = snap_time(E->get().pos + motion);
undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", E->key().track, newpos);
}
// 5 - (Undo) Reinsert keys.
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", E->key().track, E->get().pos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
}
@@ -5217,7 +5315,7 @@ void AnimationTrackEditor::_move_selection_commit() {
undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation);
// 7 - Reselect.
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
float oldpos = E->get().pos;
float newpos = snap_time(oldpos + motion);
@@ -5390,7 +5488,7 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) {
if (selection.size() && animation.is_valid() && (!transpose || (_get_track_selected() >= 0 && _get_track_selected() < animation->get_track_count()))) {
int top_track = 0x7FFFFFFF;
float top_time = 1e10;
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
const SelectedKey &sk = E->key();
float t = animation->track_get_key_time(sk.track, sk.key);
@@ -5411,7 +5509,7 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) {
List<Pair<int, float>> new_selection_values;
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
const SelectedKey &sk = E->key();
float t = animation->track_get_key_time(sk.track, sk.key);
@@ -5446,7 +5544,7 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) {
// Reselect duplicated.
- Map<SelectedKey, KeyInfo> new_selection;
+ RBMap<SelectedKey, KeyInfo> new_selection;
for (const Pair<int, float> &E : new_selection_values) {
int track = E.first;
float time = E.second;
@@ -5724,11 +5822,11 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
List<_AnimMoveRestore> to_restore;
// 1 - Remove the keys.
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
undo_redo->add_do_method(animation.ptr(), "track_remove_key", E->key().track, E->key().key);
}
// 2 - Remove overlapped keys.
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
float newtime = (E->get().pos - from_t) * s + from_t;
int idx = animation->track_find_key(E->key().track, newtime, true);
if (idx == -1) {
@@ -5754,19 +5852,19 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
#define NEW_POS(m_ofs) (((s > 0) ? m_ofs : from_t + (len - (m_ofs - from_t))) - pivot) * ABS(s) + from_t
// 3 - Move the keys (re insert them).
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
float newpos = NEW_POS(E->get().pos);
undo_redo->add_do_method(animation.ptr(), "track_insert_key", E->key().track, newpos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
}
// 4 - (Undo) Remove inserted keys.
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
float newpos = NEW_POS(E->get().pos);
undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", E->key().track, newpos);
}
// 5 - (Undo) Reinsert keys.
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", E->key().track, E->get().pos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
}
@@ -5779,7 +5877,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation);
// 7-reselect.
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
float oldpos = E->get().pos;
float newpos = NEW_POS(oldpos);
if (newpos >= 0) {
@@ -5808,7 +5906,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
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;
+ RBSet<int> tracks_added;
for (const KeyValue<SelectedKey, KeyInfo> &E : selection) {
const SelectedKey &sk = E.key;
@@ -5862,7 +5960,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
if (selection.size()) {
undo_redo->create_action(TTR("Anim Delete Keys"));
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
undo_redo->add_do_method(animation.ptr(), "track_remove_key", E->key().track, E->key().key);
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", E->key().track, E->get().pos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
}
@@ -5917,7 +6015,7 @@ void AnimationTrackEditor::_cleanup_animation(Ref<Animation> p_animation) {
Variant::Type valid_type = Variant::NIL;
Object *obj = nullptr;
- RES res;
+ Ref<Resource> res;
Vector<StringName> leftover_path;
Node *node = root->get_node_and_resource(p_animation->track_get_path(i), res, leftover_path);
@@ -6126,8 +6224,6 @@ void AnimationTrackEditor::_pick_track_filter_input(const Ref<InputEvent> &p_ie)
}
AnimationTrackEditor::AnimationTrackEditor() {
- root = nullptr;
-
undo_redo = EditorNode::get_singleton()->get_undo_redo();
main_panel = memnew(PanelContainer);
@@ -6340,8 +6436,6 @@ AnimationTrackEditor::AnimationTrackEditor() {
insert_confirm_reset->set_text(TTR("Create RESET Track(s)", ""));
insert_confirm_reset->set_pressed(EDITOR_GET("editors/animation/default_create_reset_tracks"));
ichb->add_child(insert_confirm_reset);
- key_edit = nullptr;
- multi_key_edit = nullptr;
box_selection = memnew(Control);
add_child(box_selection);