From a6dc792bbd1ebccd8d158aa6ee7d8e93659b3c25 Mon Sep 17 00:00:00 2001 From: Kasper Arnklit Frandsen Date: Thu, 11 Dec 2025 16:46:22 +0000 Subject: [PATCH] Fix the clipping of keys when moving keys --- editor/animation/animation_track_editor.cpp | 61 ++++++++++--------- editor/animation/animation_track_editor.h | 2 +- .../animation_track_editor_plugins.cpp | 18 +++--- .../animation_track_editor_plugins.h | 4 +- 4 files changed, 43 insertions(+), 42 deletions(-) diff --git a/editor/animation/animation_track_editor.cpp b/editor/animation/animation_track_editor.cpp index b70e47befb1..eeffe927030 100644 --- a/editor/animation/animation_track_editor.cpp +++ b/editor/animation/animation_track_editor.cpp @@ -2335,36 +2335,37 @@ void AnimationTrackEdit::_notification(int p_what) { { float scale = timeline->get_zoom_scale(); + // Pre-calculate the actual order of the keys. This is needed as a move might be happening + // which might cause the keys to be in a different order than their current indices. + Vector> sorted_keys; + for (int i = 0; i < animation->track_get_key_count(track); i++) { - float offset = animation->track_get_key_time(track, i) - timeline->get_value(); + float time_offset = animation->track_get_key_time(track, i) - timeline->get_value(); if (editor->is_key_selected(track, i) && editor->is_moving_selection()) { - offset = offset + editor->get_moving_selection_offset(); - } - offset = offset * scale + limit; - if (i < animation->track_get_key_count(track) - 1) { - float offset_n = animation->track_get_key_time(track, i + 1) - timeline->get_value(); - if (editor->is_key_selected(track, i + 1) && editor->is_moving_selection()) { - offset_n = offset_n + editor->get_moving_selection_offset(); - } - offset_n = offset_n * scale + limit; - float offset_last = limit_end; - if (i < animation->track_get_key_count(track) - 2) { - offset_last = animation->track_get_key_time(track, i + 2) - timeline->get_value(); - if (editor->is_key_selected(track, i + 2) && editor->is_moving_selection()) { - offset_last = offset_last + editor->get_moving_selection_offset(); - } - offset_last = offset_last * scale + limit; - } - int limit_string = (editor->is_key_selected(track, i + 1) && editor->is_moving_selection()) ? int(offset_last) : int(offset_n); - if (editor->is_key_selected(track, i) && editor->is_moving_selection()) { - limit_string = int(MAX(limit_end, offset_last)); - } - draw_key_link(i, scale, int(offset), int(offset_n), limit, limit_end); - draw_key(i, scale, int(offset), editor->is_key_selected(track, i), limit, limit_string); - continue; + time_offset += editor->get_moving_selection_offset(); } - draw_key(i, scale, int(offset), editor->is_key_selected(track, i), limit, limit_end); + float screen_pos = time_offset * scale + limit; + sorted_keys.push_back(Pair(screen_pos, i)); + } + + sorted_keys.sort(); + + for (int i = 0; i < sorted_keys.size(); i++) { + float offset = sorted_keys[i].first; + int original_index = sorted_keys[i].second; + bool selected = editor->is_key_selected(track, original_index); + + if (i < sorted_keys.size() - 1) { + float offset_n = sorted_keys[i + 1].first; + + int next_original_index = sorted_keys[i + 1].second; + + draw_key_link(original_index, next_original_index, scale, int(offset), int(offset_n), limit, limit_end); + draw_key(original_index, scale, int(offset), selected, limit, MIN(offset_n, limit_end)); + } else { + draw_key(original_index, scale, int(offset), selected, limit, limit_end); + } } } @@ -2591,7 +2592,7 @@ bool AnimationTrackEdit::is_key_selectable_by_distance() const { return true; } -void AnimationTrackEdit::draw_key_link(int p_index, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right) { +void AnimationTrackEdit::draw_key_link(int p_index_from, int p_index_to, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right) { if (p_next_x < p_clip_left) { return; } @@ -2599,8 +2600,8 @@ void AnimationTrackEdit::draw_key_link(int p_index, float p_pixels_sec, int p_x, return; } - Variant current = animation->track_get_key_value(get_track(), p_index); - Variant next = animation->track_get_key_value(get_track(), p_index + 1); + Variant current = animation->track_get_key_value(get_track(), p_index_from); + Variant next = animation->track_get_key_value(get_track(), p_index_to); if (current != next || animation->track_get_type(get_track()) == Animation::TrackType::TYPE_METHOD) { return; } @@ -2666,7 +2667,7 @@ void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool } text += ")"; - int limit = ((p_selected && editor->is_moving_selection()) || editor->is_function_name_pressed()) ? 0 : MAX(0, p_clip_right - p_x - icon_to_draw->get_width() * 2); + int limit = editor->is_function_name_pressed() ? 0 : MAX(0, p_clip_right - p_x - icon_to_draw->get_width() * 2); 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, HORIZONTAL_ALIGNMENT_LEFT, limit, font_size, color); diff --git a/editor/animation/animation_track_editor.h b/editor/animation/animation_track_editor.h index 9af1cdb69fd..6aa13c3723e 100644 --- a/editor/animation/animation_track_editor.h +++ b/editor/animation/animation_track_editor.h @@ -522,7 +522,7 @@ public: virtual int get_key_height() const; virtual Rect2 get_key_rect(int p_index, float p_pixels_sec); virtual bool is_key_selectable_by_distance() const; - virtual void draw_key_link(int p_index, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right); + virtual void draw_key_link(int p_index_from, int p_index_to, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right); virtual void draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right); virtual void draw_bg(int p_clip_left, int p_clip_right); virtual void draw_fg(int p_clip_left, int p_clip_right); diff --git a/editor/animation/animation_track_editor_plugins.cpp b/editor/animation/animation_track_editor_plugins.cpp index 6231c16ec38..f11551a7816 100644 --- a/editor/animation/animation_track_editor_plugins.cpp +++ b/editor/animation/animation_track_editor_plugins.cpp @@ -97,7 +97,7 @@ bool AnimationTrackEditColor::is_key_selectable_by_distance() const { return false; } -void AnimationTrackEditColor::draw_key_link(int p_index, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right) { +void AnimationTrackEditColor::draw_key_link(int p_index_from, int p_index_to, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right) { Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label")); int fh = (font->get_height(font_size) * 0.8); @@ -116,15 +116,15 @@ void AnimationTrackEditColor::draw_key_link(int p_index, float p_pixels_sec, int } Vector color_samples; - color_samples.append(get_animation()->track_get_key_value(get_track(), p_index)); + color_samples.append(get_animation()->track_get_key_value(get_track(), p_index_from)); if (get_animation()->track_get_type(get_track()) == Animation::TYPE_VALUE) { if (get_animation()->track_get_interpolation_type(get_track()) != Animation::INTERPOLATION_NEAREST && (get_animation()->value_track_get_update_mode(get_track()) == Animation::UPDATE_CONTINUOUS || get_animation()->value_track_get_update_mode(get_track()) == Animation::UPDATE_CAPTURE) && - !Math::is_zero_approx(get_animation()->track_get_key_transition(get_track(), p_index))) { - float start_time = get_animation()->track_get_key_time(get_track(), p_index); - float end_time = get_animation()->track_get_key_time(get_track(), p_index + 1); + !Math::is_zero_approx(get_animation()->track_get_key_transition(get_track(), p_index_from))) { + float start_time = get_animation()->track_get_key_time(get_track(), p_index_from); + float end_time = get_animation()->track_get_key_time(get_track(), p_index_to); Color color_next = get_animation()->value_track_interpolate(get_track(), end_time); @@ -142,7 +142,7 @@ void AnimationTrackEditColor::draw_key_link(int p_index, float p_pixels_sec, int color_samples.append(color_samples[0]); } } else { - color_samples.append(get_animation()->track_get_key_value(get_track(), p_index + 1)); + color_samples.append(get_animation()->track_get_key_value(get_track(), p_index_to)); } for (int i = 0; i < color_samples.size() - 1; i++) { @@ -747,13 +747,13 @@ void AnimationTrackEditVolumeDB::draw_fg(int p_clip_left, int p_clip_right) { draw_line(Vector2(p_clip_left, db0), Vector2(p_clip_right, db0), Color(1, 1, 1, 0.3)); } -void AnimationTrackEditVolumeDB::draw_key_link(int p_index, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right) { +void AnimationTrackEditVolumeDB::draw_key_link(int p_index_from, int p_index_to, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right) { if (p_x > p_clip_right || p_next_x < p_clip_left) { return; } - float db = get_animation()->track_get_key_value(get_track(), p_index); - float db_n = get_animation()->track_get_key_value(get_track(), p_index + 1); + float db = get_animation()->track_get_key_value(get_track(), p_index_from); + float db_n = get_animation()->track_get_key_value(get_track(), p_index_to); db = CLAMP(db, -60, 24); db_n = CLAMP(db_n, -60, 24); diff --git a/editor/animation/animation_track_editor_plugins.h b/editor/animation/animation_track_editor_plugins.h index d652049eaf4..7e51d43e77d 100644 --- a/editor/animation/animation_track_editor_plugins.h +++ b/editor/animation/animation_track_editor_plugins.h @@ -50,7 +50,7 @@ public: virtual Rect2 get_key_rect(int p_index, float p_pixels_sec) override; virtual bool is_key_selectable_by_distance() const override; virtual void draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) override; - virtual void draw_key_link(int p_index, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right) override; + virtual void draw_key_link(int p_index_from, int p_index_to, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right) override; }; class AnimationTrackEditAudio : public AnimationTrackEdit { @@ -150,7 +150,7 @@ public: virtual void draw_bg(int p_clip_left, int p_clip_right) override; virtual void draw_fg(int p_clip_left, int p_clip_right) override; virtual int get_key_height() const override; - virtual void draw_key_link(int p_index, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right) override; + virtual void draw_key_link(int p_index_from, int p_index_to, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right) override; }; class AnimationTrackEditDefaultPlugin : public AnimationTrackEditPlugin {