diff --git a/pandatool/src/gtk-stats/gtkStatsTimeline.cxx b/pandatool/src/gtk-stats/gtkStatsTimeline.cxx index 5010b2dabc..bffdd32e57 100644 --- a/pandatool/src/gtk-stats/gtkStatsTimeline.cxx +++ b/pandatool/src/gtk-stats/gtkStatsTimeline.cxx @@ -54,7 +54,8 @@ GtkStatsTimeline(GtkStatsMonitor *monitor) : G_CALLBACK(thread_area_draw_callback), this); // Listen for mouse wheel and keyboard events. - gtk_widget_add_events(_graph_window, GDK_SCROLL_MASK | + gtk_widget_add_events(_graph_window, GDK_SMOOTH_SCROLL_MASK | + GDK_SCROLL_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); gtk_widget_set_can_focus(_graph_window, TRUE); @@ -65,6 +66,25 @@ GtkStatsTimeline(GtkStatsMonitor *monitor) : g_signal_connect(G_OBJECT(_graph_window), "key_release_event", G_CALLBACK(key_release_callback), this); + // Set up trackpad pinch and swipe gestures. + _zoom_gesture = gtk_gesture_zoom_new(_graph_window); + g_signal_connect(_zoom_gesture, "begin", + G_CALLBACK(+[](GtkGestureZoom *gesture, GdkEventSequence *sequence, gpointer data) { + GtkStatsTimeline *self = (GtkStatsTimeline *)data; + self->_zoom_scale = self->get_horizontal_scale(); + }), this); + + g_signal_connect(_zoom_gesture, "scale-changed", + G_CALLBACK((+[](GtkGestureZoom *gesture, gdouble scale, gpointer data) { + GtkStatsTimeline *self = (GtkStatsTimeline *)data; + gdouble x, y; + if (gtk_gesture_get_point(GTK_GESTURE(gesture), NULL, &x, &y)) { + int graph_x = (int)(x * self->_cr_scale); + self->zoom_by(log(scale) * 0.8, self->pixel_to_timestamp(graph_x)); + self->start_animation(); + } + })), this); + int min_height = 0; if (!_threads.empty()) { double height = row_to_pixel(get_num_rows()) + _pixel_scale * 2.5; @@ -100,6 +120,7 @@ GtkStatsTimeline(GtkStatsMonitor *monitor) : GtkStatsTimeline:: ~GtkStatsTimeline() { cairo_pattern_destroy(_grid_pattern); + g_object_unref(_zoom_gesture); } /** @@ -627,6 +648,16 @@ handle_scroll(int graph_x, int graph_y, double dx, double dy, bool ctrl_held) { return handled; } +/** + * + */ +gboolean GtkStatsTimeline:: +handle_zoom(int graph_x, int graph_y, double scale) { + zoom_to(get_horizontal_scale() / scale, pixel_to_timestamp(graph_x)); + start_animation(); + return TRUE; +} + /** * */ diff --git a/pandatool/src/gtk-stats/gtkStatsTimeline.h b/pandatool/src/gtk-stats/gtkStatsTimeline.h index 37f3f38167..b354712d66 100644 --- a/pandatool/src/gtk-stats/gtkStatsTimeline.h +++ b/pandatool/src/gtk-stats/gtkStatsTimeline.h @@ -63,6 +63,7 @@ protected: virtual gboolean handle_leave(); gboolean handle_scroll(int graph_x, int graph_y, double dx, double dy, bool ctrl_held); + gboolean handle_zoom(int graph_x, int graph_y, double scale); gboolean handle_key(bool pressed, guint val, guint16 hw_code); private: @@ -92,6 +93,9 @@ private: int _highlighted_x = 0; int _scroll = 0; ColorBar _popup_bar; + + double _zoom_scale = 1.0; + GtkGesture *_zoom_gesture = nullptr; }; #endif