Merge pull request #93408 from CookieBadger/animation-track-key-inspector-fix

Fix displaying selected Bezier animation keys in inspector
This commit is contained in:
Rémi Verschelde 2024-06-28 11:34:52 +02:00
commit eeef96b144
No known key found for this signature in database
GPG key ID: C3336907360768E1
3 changed files with 40 additions and 21 deletions

View file

@ -682,6 +682,7 @@ void AnimationBezierTrackEdit::set_editor(AnimationTrackEditor *p_editor) {
editor = p_editor; editor = p_editor;
connect("clear_selection", callable_mp(editor, &AnimationTrackEditor::_clear_selection).bind(false)); connect("clear_selection", callable_mp(editor, &AnimationTrackEditor::_clear_selection).bind(false));
connect("select_key", callable_mp(editor, &AnimationTrackEditor::_key_selected), CONNECT_DEFERRED); connect("select_key", callable_mp(editor, &AnimationTrackEditor::_key_selected), CONNECT_DEFERRED);
connect("deselect_key", callable_mp(editor, &AnimationTrackEditor::_key_deselected), CONNECT_DEFERRED);
} }
void AnimationBezierTrackEdit::_play_position_draw() { void AnimationBezierTrackEdit::_play_position_draw() {
@ -877,7 +878,7 @@ void AnimationBezierTrackEdit::_clear_selection_for_anim(const Ref<Animation> &p
_clear_selection(); _clear_selection();
} }
void AnimationBezierTrackEdit::_select_at_anim(const Ref<Animation> &p_anim, int p_track, real_t p_pos) { void AnimationBezierTrackEdit::_select_at_anim(const Ref<Animation> &p_anim, int p_track, real_t p_pos, bool p_single) {
if (!(animation == p_anim)) { if (!(animation == p_anim)) {
return; return;
} }
@ -886,7 +887,7 @@ void AnimationBezierTrackEdit::_select_at_anim(const Ref<Animation> &p_anim, int
ERR_FAIL_COND(idx < 0); ERR_FAIL_COND(idx < 0);
selection.insert(IntPair(p_track, idx)); selection.insert(IntPair(p_track, idx));
emit_signal(SNAME("select_key"), idx, true, p_track); emit_signal(SNAME("select_key"), idx, p_single, p_track);
queue_redraw(); queue_redraw();
} }
@ -1002,7 +1003,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
return; return;
} else if (ED_IS_SHORTCUT("animation_bezier_editor/select_all_keys", p_event)) { } else if (ED_IS_SHORTCUT("animation_bezier_editor/select_all_keys", p_event)) {
for (int i = 0; i < edit_points.size(); ++i) { for (int i = 0; i < edit_points.size(); ++i) {
selection.insert(IntPair(edit_points[i].track, edit_points[i].key)); _select_at_anim(animation, edit_points[i].track, animation->track_get_key_time(edit_points[i].track, edit_points[i].key), i == 0);
} }
queue_redraw(); queue_redraw();
@ -1010,6 +1011,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
return; return;
} else if (ED_IS_SHORTCUT("animation_bezier_editor/deselect_all_keys", p_event)) { } else if (ED_IS_SHORTCUT("animation_bezier_editor/deselect_all_keys", p_event)) {
selection.clear(); selection.clear();
emit_signal(SNAME("clear_selection"));
queue_redraw(); queue_redraw();
accept_event(); accept_event();
@ -1235,7 +1237,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
int index = animation->track_find_key(selected_track, time, Animation::FIND_MODE_APPROX); int index = animation->track_find_key(selected_track, time, Animation::FIND_MODE_APPROX);
ERR_FAIL_COND(index == -1); ERR_FAIL_COND(index == -1);
_clear_selection(); _clear_selection();
selection.insert(IntPair(selected_track, index)); _select_at_anim(animation, selected_track, animation->track_get_key_time(selected_track, index), true);
moving_selection_attempt = true; moving_selection_attempt = true;
moving_selection = false; moving_selection = false;
@ -1277,13 +1279,15 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
Rect2 selection_rect(bs_from, bs_to - bs_from); Rect2 selection_rect(bs_from, bs_to - bs_from);
bool track_set = false; bool track_set = false;
int j = 0;
for (int i = 0; i < edit_points.size(); i++) { for (int i = 0; i < edit_points.size(); i++) {
if (edit_points[i].point_rect.intersects(selection_rect)) { if (edit_points[i].point_rect.intersects(selection_rect)) {
selection.insert(IntPair(edit_points[i].track, edit_points[i].key)); _select_at_anim(animation, edit_points[i].track, animation->track_get_key_time(edit_points[i].track, edit_points[i].key), j == 0 && !box_selecting_add);
if (!track_set) { if (!track_set) {
track_set = true; track_set = true;
set_animation_and_track(animation, edit_points[i].track, read_only); set_animation_and_track(animation, edit_points[i].track, read_only);
} }
j++;
} }
} }
} else { } else {
@ -1418,21 +1422,22 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation); undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation);
// 7-reselect // 7-reselect
int i = 0;
for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) { for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) {
real_t oldpos = animation->track_get_key_time(E->get().first, E->get().second); real_t oldpos = animation->track_get_key_time(E->get().first, E->get().second);
real_t newpos = oldpos + moving_selection_offset.x; real_t newpos = oldpos + moving_selection_offset.x;
undo_redo->add_do_method(this, "_select_at_anim", animation, E->get().first, newpos); undo_redo->add_do_method(this, "_select_at_anim", animation, E->get().first, newpos, i == 0);
undo_redo->add_undo_method(this, "_select_at_anim", animation, E->get().first, oldpos); undo_redo->add_undo_method(this, "_select_at_anim", animation, E->get().first, oldpos, i == 0);
i++;
} }
undo_redo->commit_action(); undo_redo->commit_action();
} else if (select_single_attempt != IntPair(-1, -1)) { } else if (select_single_attempt != IntPair(-1, -1)) {
selection.clear(); selection.clear();
selection.insert(select_single_attempt);
set_animation_and_track(animation, select_single_attempt.first, read_only); set_animation_and_track(animation, select_single_attempt.first, read_only);
_select_at_anim(animation, select_single_attempt.first, animation->track_get_key_time(select_single_attempt.first, select_single_attempt.second), true);
} }
moving_selection = false; moving_selection = false;
@ -1567,9 +1572,10 @@ bool AnimationBezierTrackEdit::_try_select_at_ui_pos(const Point2 &p_pos, bool p
if (selection.has(pair)) { if (selection.has(pair)) {
if (p_deselectable) { if (p_deselectable) {
selection.erase(pair); selection.erase(pair);
emit_signal(SNAME("deselect_key"), edit_points[i].key, edit_points[i].track);
} }
} else { } else {
selection.insert(pair); _select_at_anim(animation, edit_points[i].track, animation->track_get_key_time(edit_points[i].track, edit_points[i].key), false);
} }
queue_redraw(); queue_redraw();
select_single_attempt = IntPair(-1, -1); select_single_attempt = IntPair(-1, -1);
@ -1595,7 +1601,7 @@ bool AnimationBezierTrackEdit::_try_select_at_ui_pos(const Point2 &p_pos, bool p
set_animation_and_track(animation, pair.first, read_only); set_animation_and_track(animation, pair.first, read_only);
if (!selection.has(pair)) { if (!selection.has(pair)) {
selection.clear(); selection.clear();
selection.insert(pair); _select_at_anim(animation, edit_points[i].track, animation->track_get_key_time(edit_points[i].track, edit_points[i].key), true);
} }
} }
return true; return true;
@ -1763,12 +1769,16 @@ void AnimationBezierTrackEdit::duplicate_selected_keys(real_t p_ofs, bool p_ofs_
undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation); undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation);
// Reselect duplicated. // Reselect duplicated.
int i = 0;
for (const Pair<int, real_t> &E : new_selection_values) { for (const Pair<int, real_t> &E : new_selection_values) {
undo_redo->add_do_method(this, "_select_at_anim", animation, E.first, E.second); undo_redo->add_do_method(this, "_select_at_anim", animation, E.first, E.second, i == 0);
i++;
} }
i = 0;
for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) { for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) {
real_t time = animation->track_get_key_time(E->get().first, E->get().second); real_t time = animation->track_get_key_time(E->get().first, E->get().second);
undo_redo->add_undo_method(this, "_select_at_anim", animation, E->get().first, time); undo_redo->add_undo_method(this, "_select_at_anim", animation, E->get().first, time, i == 0);
i++;
} }
undo_redo->add_do_method(this, "queue_redraw"); undo_redo->add_do_method(this, "queue_redraw");
@ -1805,16 +1815,20 @@ void AnimationBezierTrackEdit::copy_selected_keys(bool p_cut) {
undo_redo->create_action(TTR("Animation Cut Keys"), UndoRedo::MERGE_DISABLE, animation.ptr()); undo_redo->create_action(TTR("Animation Cut Keys"), UndoRedo::MERGE_DISABLE, animation.ptr());
undo_redo->add_do_method(this, "_clear_selection_for_anim", animation); undo_redo->add_do_method(this, "_clear_selection_for_anim", animation);
undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation); undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation);
int i = 0;
for (RBMap<AnimationTrackEditor::SelectedKey, AnimationTrackEditor::KeyInfo>::Element *E = keys.back(); E; E = E->prev()) { for (RBMap<AnimationTrackEditor::SelectedKey, AnimationTrackEditor::KeyInfo>::Element *E = keys.back(); E; E = E->prev()) {
int track_idx = E->key().track; int track_idx = E->key().track;
int key_idx = E->key().key; int key_idx = E->key().key;
float time = E->value().pos; float time = E->value().pos;
undo_redo->add_do_method(animation.ptr(), "track_remove_key_at_time", track_idx, time); undo_redo->add_do_method(animation.ptr(), "track_remove_key_at_time", track_idx, time);
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", track_idx, time, animation->track_get_key_value(track_idx, key_idx), animation->track_get_key_transition(track_idx, key_idx)); undo_redo->add_undo_method(animation.ptr(), "track_insert_key", track_idx, time, animation->track_get_key_value(track_idx, key_idx), animation->track_get_key_transition(track_idx, key_idx));
undo_redo->add_undo_method(this, "_select_at_anim", animation, track_idx, time); undo_redo->add_undo_method(this, "_select_at_anim", animation, track_idx, time, i == 0);
i++;
} }
i = 0;
for (RBMap<AnimationTrackEditor::SelectedKey, AnimationTrackEditor::KeyInfo>::Element *E = keys.back(); E; E = E->prev()) { for (RBMap<AnimationTrackEditor::SelectedKey, AnimationTrackEditor::KeyInfo>::Element *E = keys.back(); E; E = E->prev()) {
undo_redo->add_undo_method(this, "_select_at_anim", animation, E->key().track, E->value().pos); undo_redo->add_undo_method(this, "_select_at_anim", animation, E->key().track, E->value().pos, i == 0);
i++;
} }
undo_redo->commit_action(); undo_redo->commit_action();
} }
@ -1883,11 +1897,15 @@ void AnimationBezierTrackEdit::paste_keys(real_t p_ofs, bool p_ofs_valid) {
undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation); undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation);
// Reselect pasted. // Reselect pasted.
int i = 0;
for (const Pair<int, float> &E : new_selection_values) { for (const Pair<int, float> &E : new_selection_values) {
undo_redo->add_do_method(this, "_select_at_anim", animation, E.first, E.second); undo_redo->add_do_method(this, "_select_at_anim", animation, E.first, E.second, i == 0);
i++;
} }
i = 0;
for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) { for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) {
undo_redo->add_undo_method(this, "_select_at_anim", animation, E->get().first, animation->track_get_key_time(E->get().first, E->get().second)); undo_redo->add_undo_method(this, "_select_at_anim", animation, E->get().first, animation->track_get_key_time(E->get().first, E->get().second), i == 0);
i++;
} }
undo_redo->commit_action(); undo_redo->commit_action();
@ -1928,6 +1946,7 @@ void AnimationBezierTrackEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("_bezier_track_insert_key"), &AnimationBezierTrackEdit::_bezier_track_insert_key); ClassDB::bind_method(D_METHOD("_bezier_track_insert_key"), &AnimationBezierTrackEdit::_bezier_track_insert_key);
ADD_SIGNAL(MethodInfo("select_key", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::BOOL, "single"), PropertyInfo(Variant::INT, "track"))); ADD_SIGNAL(MethodInfo("select_key", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::BOOL, "single"), PropertyInfo(Variant::INT, "track")));
ADD_SIGNAL(MethodInfo("deselect_key", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::INT, "track")));
ADD_SIGNAL(MethodInfo("clear_selection")); ADD_SIGNAL(MethodInfo("clear_selection"));
} }

View file

@ -144,7 +144,7 @@ class AnimationBezierTrackEdit : public Control {
void _clear_selection(); void _clear_selection();
void _clear_selection_for_anim(const Ref<Animation> &p_anim); void _clear_selection_for_anim(const Ref<Animation> &p_anim);
void _select_at_anim(const Ref<Animation> &p_anim, int p_track, real_t p_pos); void _select_at_anim(const Ref<Animation> &p_anim, int p_track, real_t p_pos, bool p_single);
bool _try_select_at_ui_pos(const Point2 &p_pos, bool p_aggregate, bool p_deselectable); bool _try_select_at_ui_pos(const Point2 &p_pos, bool p_aggregate, bool p_deselectable);
void _change_selected_keys_handle_mode(Animation::HandleMode p_mode, bool p_auto = false); void _change_selected_keys_handle_mode(Animation::HandleMode p_mode, bool p_auto = false);

View file

@ -874,15 +874,15 @@ bool AnimationMultiTrackKeyEdit::_set(const StringName &p_name, const Variant &p
undo_redo->create_action(TTR("Animation Multi Change Keyframe Value"), UndoRedo::MERGE_ENDS); undo_redo->create_action(TTR("Animation Multi Change Keyframe Value"), UndoRedo::MERGE_ENDS);
} }
Vector2 prev = animation->bezier_track_get_key_out_handle(track, key); Vector2 prev = animation->bezier_track_get_key_out_handle(track, key);
undo_redo->add_do_method(this, "_bezier_track_set_key_out_handle", track, key, value); undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_out_handle", track, key, value);
undo_redo->add_undo_method(this, "_bezier_track_set_key_out_handle", track, key, prev); undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_out_handle", track, key, prev);
update_obj = true; update_obj = true;
} else if (name == "handle_mode") { } else if (name == "handle_mode") {
const Variant &value = p_value; const Variant &value = p_value;
if (!setting) { if (!setting) {
setting = true; setting = true;
undo_redo->create_action(TTR("Animation Multi Change Keyframe Value"), UndoRedo::MERGE_ENDS); undo_redo->create_action(TTR("Animation Multi Change Keyframe Value"), UndoRedo::MERGE_ENDS, animation.ptr());
} }
int prev_mode = animation->bezier_track_get_key_handle_mode(track, key); int prev_mode = animation->bezier_track_get_key_handle_mode(track, key);
Vector2 prev_in_handle = animation->bezier_track_get_key_in_handle(track, key); Vector2 prev_in_handle = animation->bezier_track_get_key_in_handle(track, key);