From efc6f0d2148441f3a30e2a66349d66461bb986f9 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 27 Feb 2024 00:57:51 +0100 Subject: [PATCH] Add Ctrl+scrollwheel zoom to the timeline (#2781). --- src/wx/timeline.cc | 38 ++++++++++++++++++++++++++++++++++++++ src/wx/timeline.h | 3 +++ 2 files changed, 41 insertions(+) diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc index 4683769d4..f67bf52dc 100644 --- a/src/wx/timeline.cc +++ b/src/wx/timeline.cc @@ -109,6 +109,7 @@ Timeline::Timeline(wxWindow* parent, ContentPanel* cp, shared_ptr film, Fi _main_canvas->Bind (wxEVT_RIGHT_DOWN, boost::bind (&Timeline::right_down, this, _1)); _main_canvas->Bind (wxEVT_MOTION, boost::bind (&Timeline::mouse_moved, this, _1)); _main_canvas->Bind (wxEVT_SIZE, boost::bind (&Timeline::resized, this)); + _main_canvas->Bind (wxEVT_MOUSEWHEEL, boost::bind(&Timeline::mouse_wheel_turned, this, _1)); _main_canvas->Bind (wxEVT_SCROLLWIN_TOP, boost::bind (&Timeline::scrolled, this, _1)); _main_canvas->Bind (wxEVT_SCROLLWIN_BOTTOM, boost::bind (&Timeline::scrolled, this, _1)); _main_canvas->Bind (wxEVT_SCROLLWIN_LINEUP, boost::bind (&Timeline::scrolled, this, _1)); @@ -132,6 +133,43 @@ Timeline::Timeline(wxWindow* parent, ContentPanel* cp, shared_ptr film, Fi } +void +Timeline::mouse_wheel_turned(wxMouseEvent& event) +{ + if (event.ControlDown()) { + auto const rotation = event.GetWheelRotation(); + /* On my mouse one click of the scroll wheel is 120, and it's -ve when + * scrolling the wheel towards me. + */ + auto const scale = rotation > 0 ? + (1.0 / (rotation / 90.0)) : + (-rotation / 90.0); + + int before_start_x; + int before_start_y; + _main_canvas->GetViewStart(&before_start_x, &before_start_y); + + auto const before_pps = _pixels_per_second.get_value_or(1); + auto const before_pos = _last_mouse_wheel_x && *_last_mouse_wheel_x == event.GetX() ? + *_last_mouse_wheel_time : + (before_start_x * _x_scroll_rate + event.GetX()) / before_pps; + + set_pixels_per_second(before_pps * scale); + setup_scrollbars(); + + auto after_left = std::max(0.0, before_pos * _pixels_per_second.get_value_or(1) - event.GetX()); + _main_canvas->Scroll(after_left / _x_scroll_rate, before_start_y); + _labels_canvas->Scroll(0, before_start_y); + Refresh(); + + if (!_last_mouse_wheel_x || *_last_mouse_wheel_x != event.GetX()) { + _last_mouse_wheel_x = event.GetX(); + _last_mouse_wheel_time = before_pos; + } + } +} + + void Timeline::update_playhead () { diff --git a/src/wx/timeline.h b/src/wx/timeline.h index 2485e835f..621609fa7 100644 --- a/src/wx/timeline.h +++ b/src/wx/timeline.h @@ -110,6 +110,7 @@ private: void set_pixels_per_track (int h); void zoom_all (); void update_playhead (); + void mouse_wheel_turned(wxMouseEvent& event); std::shared_ptr event_to_view (wxMouseEvent &); TimelineContentViewList selected_views () const; @@ -143,6 +144,8 @@ private: int _pixels_per_track; bool _first_resize; wxTimer _timer; + boost::optional _last_mouse_wheel_x; + boost::optional _last_mouse_wheel_time; static double const _minimum_pixels_per_second; static int const _minimum_pixels_per_track; -- 2.30.2