summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2024-02-27 00:57:51 +0100
committerCarl Hetherington <cth@carlh.net>2024-02-27 00:57:51 +0100
commitefc6f0d2148441f3a30e2a66349d66461bb986f9 (patch)
treefce7c71e46689a240029bd4819d10dc85e5b6ec1
parentd8bbc508e959d8d38c54a6db6cfc868bd64697f5 (diff)
Add Ctrl+scrollwheel zoom to the timeline (#2781).
-rw-r--r--src/wx/timeline.cc38
-rw-r--r--src/wx/timeline.h3
2 files changed, 41 insertions, 0 deletions
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> 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));
@@ -133,6 +134,43 @@ Timeline::Timeline(wxWindow* parent, ContentPanel* cp, shared_ptr<Film> 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 ()
{
Refresh ();
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<TimelineView> event_to_view (wxMouseEvent &);
TimelineContentViewList selected_views () const;
@@ -143,6 +144,8 @@ private:
int _pixels_per_track;
bool _first_resize;
wxTimer _timer;
+ boost::optional<int> _last_mouse_wheel_x;
+ boost::optional<double> _last_mouse_wheel_time;
static double const _minimum_pixels_per_second;
static int const _minimum_pixels_per_track;