From 86fc8ef99b6b3befb7ac604ece31354f0244892f Mon Sep 17 00:00:00 2001 From: Saracen Date: Thu, 12 Sep 2024 10:22:11 +0100 Subject: [PATCH] Fix selection box + scrolling in animation editor. --- editor/animation_track_editor.cpp | 65 +++++++++++++++++++++++++------ editor/animation_track_editor.h | 8 ++++ 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 4ec097bdda2..4ce5e7440c6 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -5705,9 +5705,11 @@ void AnimationTrackEditor::_box_selection_draw() { } void AnimationTrackEditor::_scroll_input(const Ref &p_event) { - if (panner->gui_input(p_event)) { - scroll->accept_event(); - return; + if (!box_selecting) { + if (panner->gui_input(p_event)) { + scroll->accept_event(); + return; + } } Ref mb = p_event; @@ -5758,6 +5760,8 @@ void AnimationTrackEditor::_scroll_input(const Ref &p_event) { Vector2 from = box_selecting_from; Vector2 to = scroll->get_global_transform().xform(mm->get_position()); + box_selecting_to = to; + if (from.x > to.x) { SWAP(from.x, to.x); } @@ -5767,11 +5771,7 @@ void AnimationTrackEditor::_scroll_input(const Ref &p_event) { } Rect2 rect(from, to - from); - Rect2 scroll_rect = Rect2(scroll->get_global_position(), scroll->get_size()); - rect = scroll_rect.intersection(rect); - box_selection->set_position(rect.position); - box_selection->set_size(rect.size); - + box_selection->set_rect(Rect2(from - scroll->get_global_position(), rect.get_size())); box_select_rect = rect; } } @@ -5790,6 +5790,39 @@ void AnimationTrackEditor::_toggle_bezier_edit() { } } +void AnimationTrackEditor::_scroll_changed(const Vector2 &p_val) { + if (box_selecting) { + const Vector2 scroll_difference = p_val - prev_scroll_position; + + Vector2 from = box_selecting_from - scroll_difference; + Vector2 to = box_selecting_to; + + box_selecting_from = from; + + if (from.x > to.x) { + SWAP(from.x, to.x); + } + + if (from.y > to.y) { + SWAP(from.y, to.y); + } + + Rect2 rect(from, to - from); + box_selection->set_rect(Rect2(from - scroll->get_global_position(), rect.get_size())); + box_select_rect = rect; + } + + prev_scroll_position = p_val; +} + +void AnimationTrackEditor::_v_scroll_changed(float p_val) { + _scroll_changed(Vector2(prev_scroll_position.x, p_val)); +} + +void AnimationTrackEditor::_h_scroll_changed(float p_val) { + _scroll_changed(Vector2(p_val, prev_scroll_position.y)); +} + void AnimationTrackEditor::_pan_callback(Vector2 p_scroll_vec, Ref p_event) { Ref iewm = p_event; if (iewm.is_valid() && iewm->is_alt_pressed()) { @@ -7290,9 +7323,15 @@ AnimationTrackEditor::AnimationTrackEditor() { panner->set_scroll_zoom_factor(AnimationTimelineEdit::SCROLL_ZOOM_FACTOR_IN); panner->set_callbacks(callable_mp(this, &AnimationTrackEditor::_pan_callback), callable_mp(this, &AnimationTrackEditor::_zoom_callback)); + box_selection_container = memnew(Control); + box_selection_container->set_v_size_flags(SIZE_EXPAND_FILL); + box_selection_container->set_clip_contents(true); + timeline_vbox->add_child(box_selection_container); + scroll = memnew(ScrollContainer); - timeline_vbox->add_child(scroll); - scroll->set_v_size_flags(SIZE_EXPAND_FILL); + box_selection_container->add_child(scroll); + scroll->set_anchors_and_offsets_preset(PRESET_FULL_RECT); + 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. @@ -7300,6 +7339,9 @@ AnimationTrackEditor::AnimationTrackEditor() { scroll->connect(SceneStringName(gui_input), callable_mp(this, &AnimationTrackEditor::_scroll_input)); scroll->connect(SceneStringName(focus_exited), callable_mp(panner.ptr(), &ViewPanner::release_pan_key)); + scroll->get_v_scroll_bar()->connect(SceneStringName(value_changed), callable_mp(this, &AnimationTrackEditor::_v_scroll_changed)); + scroll->get_h_scroll_bar()->connect(SceneStringName(value_changed), callable_mp(this, &AnimationTrackEditor::_h_scroll_changed)); + bezier_edit = memnew(AnimationBezierTrackEdit); timeline_vbox->add_child(bezier_edit); bezier_edit->set_editor(this); @@ -7513,8 +7555,7 @@ AnimationTrackEditor::AnimationTrackEditor() { ichb->add_child(insert_confirm_reset); box_selection = memnew(Control); - add_child(box_selection); - box_selection->set_as_top_level(true); + box_selection_container->add_child(box_selection); box_selection->set_mouse_filter(MOUSE_FILTER_IGNORE); box_selection->hide(); box_selection->connect(SceneStringName(draw), callable_mp(this, &AnimationTrackEditor::_box_selection_draw)); diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index 8a263d7d209..99f28074562 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -498,6 +498,10 @@ class AnimationTrackEditor : public VBoxContainer { PropertyInfo _find_hint_for_track(int p_idx, NodePath &r_base_path, Variant *r_current_val = nullptr); + void _scroll_changed(const Vector2 &p_val); + void _v_scroll_changed(float p_val); + void _h_scroll_changed(float p_val); + Ref panner; void _pan_callback(Vector2 p_scroll_vec, Ref p_event); void _zoom_callback(float p_zoom_factor, Vector2 p_origin, Ref p_event); @@ -540,11 +544,15 @@ class AnimationTrackEditor : public VBoxContainer { void _update_key_edit(); void _clear_key_edit(); + Control *box_selection_container = nullptr; + Control *box_selection = nullptr; void _box_selection_draw(); bool box_selecting = false; Vector2 box_selecting_from; + Vector2 box_selecting_to; Rect2 box_select_rect; + Vector2 prev_scroll_position; void _scroll_input(const Ref &p_event); Vector> track_edit_plugins;