[evince/wip/gpoo/gtk4-rebase-port: 64/96] ev-view: implement middle click drag
- From: Germán Poo-Caamaño <gpoo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince/wip/gpoo/gtk4-rebase-port: 64/96] ev-view: implement middle click drag
- Date: Sun, 20 Mar 2022 21:50:30 +0000 (UTC)
commit c821ed4febdba8dadda39e7906e44f9f4d458c79
Author: Qiu Wenbo <qiuwenbo kylinos com cn>
Date: Wed Aug 18 17:27:03 2021 +0800
ev-view: implement middle click drag
Signed-off-by: Qiu Wenbo <qiuwenbo kylinos com cn>
libview/ev-view.c | 301 ++++++++++++++++++++++++++++++------------------------
1 file changed, 165 insertions(+), 136 deletions(-)
---
diff --git a/libview/ev-view.c b/libview/ev-view.c
index bec31a386..0e30b3205 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -5641,17 +5641,7 @@ ev_view_button_press_event (GtkGestureClick *gesture,
}
return;
case GDK_BUTTON_MIDDLE:
-#if 0
- /* use root coordinates as reference point because
- * scrolling changes window relative coordinates */
- view->drag_info.start.x = event->x_root;
- view->drag_info.start.y = event->y_root;
- view->drag_info.hadj = gtk_adjustment_get_value (view->hadjustment);
- view->drag_info.vadj = gtk_adjustment_get_value (view->vadjustment);
-
- ev_view_set_cursor (view, EV_VIEW_CURSOR_DRAG);
ev_view_set_focused_element_at_location (view, x, y);
-#endif
return;
case GDK_BUTTON_SECONDARY:
view->scroll_info.start_y = y;
@@ -5660,6 +5650,160 @@ ev_view_button_press_event (GtkGestureClick *gesture,
}
}
+static gboolean
+ev_view_drag_update_momentum (EvView *view)
+{
+ int i;
+ if (!view->drag_info.in_drag)
+ return FALSE;
+
+ for (i = DRAG_HISTORY - 1; i > 0; i--) {
+ view->drag_info.buffer[i].x = view->drag_info.buffer[i-1].x;
+ view->drag_info.buffer[i].y = view->drag_info.buffer[i-1].y;
+ }
+
+ /* Momentum is a moving average of 10ms granularity over
+ * the last 100ms with each 10ms stored in buffer.
+ */
+
+ view->drag_info.momentum.x = (view->drag_info.buffer[DRAG_HISTORY - 1].x -
view->drag_info.buffer[0].x);
+ view->drag_info.momentum.y = (view->drag_info.buffer[DRAG_HISTORY - 1].y -
view->drag_info.buffer[0].y);
+
+ return TRUE;
+}
+
+static gboolean
+ev_view_scroll_drag_release (EvView *view)
+{
+ gdouble dhadj_value, dvadj_value;
+ gdouble oldhadjustment, oldvadjustment;
+ gdouble h_page_size, v_page_size;
+ gdouble h_upper, v_upper;
+ GtkAllocation allocation;
+
+ view->drag_info.momentum.x /= 1.2;
+ view->drag_info.momentum.y /= 1.2; /* Alter these constants to change "friction" */
+
+ gtk_widget_get_allocation (GTK_WIDGET (view), &allocation);
+
+ h_page_size = gtk_adjustment_get_page_size (view->hadjustment);
+ v_page_size = gtk_adjustment_get_page_size (view->vadjustment);
+
+ dhadj_value = h_page_size *
+ (gdouble)view->drag_info.momentum.x / allocation.width;
+ dvadj_value = v_page_size *
+ (gdouble)view->drag_info.momentum.y / allocation.height;
+
+ oldhadjustment = gtk_adjustment_get_value (view->hadjustment);
+ oldvadjustment = gtk_adjustment_get_value (view->vadjustment);
+
+ h_upper = gtk_adjustment_get_upper (view->hadjustment);
+ v_upper = gtk_adjustment_get_upper (view->vadjustment);
+
+ /* When we reach the edges, we need either to absorb some momentum and bounce by
+ * multiplying it on -0.5 or stop scrolling by setting momentum to 0. */
+ if (((oldhadjustment + dhadj_value) > (h_upper - h_page_size)) ||
+ ((oldhadjustment + dhadj_value) < 0))
+ view->drag_info.momentum.x = 0;
+ if (((oldvadjustment + dvadj_value) > (v_upper - v_page_size)) ||
+ ((oldvadjustment + dvadj_value) < 0))
+ view->drag_info.momentum.y = 0;
+
+ gtk_adjustment_set_value (view->hadjustment,
+ MIN (oldhadjustment + dhadj_value,
+ h_upper - h_page_size));
+ gtk_adjustment_set_value (view->vadjustment,
+ MIN (oldvadjustment + dvadj_value,
+ v_upper - v_page_size));
+
+ if (((view->drag_info.momentum.x < 1) && (view->drag_info.momentum.x > -1)) &&
+ ((view->drag_info.momentum.y < 1) && (view->drag_info.momentum.y > -1)))
+ return FALSE;
+ else
+ return TRUE;
+}
+
+static void
+on_middle_clicked_drag_begin (GtkGestureDrag *self,
+ gdouble start_x,
+ gdouble start_y,
+ EvView *view)
+{
+ /* use root coordinates as reference point because
+ * scrolling changes window relative coordinates */
+ view->drag_info.hadj = gtk_adjustment_get_value (view->hadjustment);
+ view->drag_info.vadj = gtk_adjustment_get_value (view->vadjustment);
+
+ ev_view_set_cursor (view, EV_VIEW_CURSOR_DRAG);
+
+ view->drag_info.drag_timeout_id = g_timeout_add (10,
+ (GSourceFunc)ev_view_drag_update_momentum, view);
+ /* Set 100 to choose how long it takes to build up momentum */
+ /* Clear out previous momentum info: */
+ for (int i = 0; i < DRAG_HISTORY; i++) {
+ view->drag_info.buffer[i].x = start_x;
+ view->drag_info.buffer[i].y = start_y;
+ }
+ view->drag_info.momentum.x = 0;
+ view->drag_info.momentum.y = 0;
+
+ view->drag_info.in_drag = TRUE;
+}
+
+static void
+on_middle_clicked_drag_end (GtkGestureDrag *self,
+ gdouble offset_x,
+ gdouble offset_y,
+ EvView *view)
+{
+ view->drag_info.release_timeout_id =
+ g_timeout_add (20, (GSourceFunc)ev_view_scroll_drag_release, view);
+
+ view->drag_info.in_drag = FALSE;
+}
+
+static void
+on_middle_clicked_drag_update (GtkGestureDrag *self,
+ gdouble offset_x,
+ gdouble offset_y,
+ EvView *view)
+{
+ GdkEvent *event = gtk_event_controller_get_current_event (GTK_EVENT_CONTROLLER (self));
+ gdouble dhadj_value, dvadj_value;
+ GtkAllocation allocation;
+
+ gtk_widget_get_allocation (GTK_WIDGET (view), &allocation);
+
+ dhadj_value = gtk_adjustment_get_page_size (view->hadjustment) *
+ offset_x / allocation.width;
+ dvadj_value = gtk_adjustment_get_page_size (view->vadjustment) *
+ offset_y / allocation.height;
+
+ /* We will update the drag event's start position if
+ * the adjustment value is changed, but only if the
+ * change was not caused by this function. */
+
+ view->drag_info.in_notify = TRUE;
+
+ /* clamp scrolling to visible area */
+ gtk_adjustment_set_value (view->hadjustment, MIN (view->drag_info.hadj - dhadj_value,
+ gtk_adjustment_get_upper (view->hadjustment) -
+ gtk_adjustment_get_page_size (view->hadjustment)));
+ gtk_adjustment_set_value (view->vadjustment, MIN (view->drag_info.vadj - dvadj_value,
+ gtk_adjustment_get_upper (view->vadjustment) -
+ gtk_adjustment_get_page_size (view->vadjustment)));
+
+ view->drag_info.in_notify = FALSE;
+
+ gdouble x, y;
+
+ gdk_event_get_axis (event, GDK_AXIS_X, &x);
+ gdk_event_get_axis (event, GDK_AXIS_Y, &y);
+
+ view->drag_info.buffer[0].x = x;
+ view->drag_info.buffer[0].y = y;
+}
+
#if 0
static void
ev_view_remove_all (EvView *view)
@@ -5803,80 +5947,6 @@ selection_scroll_timeout_cb (EvView *view)
return TRUE;
}
-static gboolean
-ev_view_drag_update_momentum (EvView *view)
-{
- int i;
- if (!view->drag_info.in_drag)
- return FALSE;
-
- for (i = DRAG_HISTORY - 1; i > 0; i--) {
- view->drag_info.buffer[i].x = view->drag_info.buffer[i-1].x;
- view->drag_info.buffer[i].y = view->drag_info.buffer[i-1].y;
- }
-
- /* Momentum is a moving average of 10ms granularity over
- * the last 100ms with each 10ms stored in buffer.
- */
-
- view->drag_info.momentum.x = (view->drag_info.buffer[DRAG_HISTORY - 1].x -
view->drag_info.buffer[0].x);
- view->drag_info.momentum.y = (view->drag_info.buffer[DRAG_HISTORY - 1].y -
view->drag_info.buffer[0].y);
-
- return TRUE;
-}
-
-static gboolean
-ev_view_scroll_drag_release (EvView *view)
-{
- gdouble dhadj_value, dvadj_value;
- gdouble oldhadjustment, oldvadjustment;
- gdouble h_page_size, v_page_size;
- gdouble h_upper, v_upper;
- GtkAllocation allocation;
-
- view->drag_info.momentum.x /= 1.2;
- view->drag_info.momentum.y /= 1.2; /* Alter these constants to change "friction" */
-
- gtk_widget_get_allocation (GTK_WIDGET (view), &allocation);
-
- h_page_size = gtk_adjustment_get_page_size (view->hadjustment);
- v_page_size = gtk_adjustment_get_page_size (view->vadjustment);
-
- dhadj_value = h_page_size *
- (gdouble)view->drag_info.momentum.x / allocation.width;
- dvadj_value = v_page_size *
- (gdouble)view->drag_info.momentum.y / allocation.height;
-
- oldhadjustment = gtk_adjustment_get_value (view->hadjustment);
- oldvadjustment = gtk_adjustment_get_value (view->vadjustment);
-
- h_upper = gtk_adjustment_get_upper (view->hadjustment);
- v_upper = gtk_adjustment_get_upper (view->vadjustment);
-
- /* When we reach the edges, we need either to absorb some momentum and bounce by
- * multiplying it on -0.5 or stop scrolling by setting momentum to 0. */
- if (((oldhadjustment + dhadj_value) > (h_upper - h_page_size)) ||
- ((oldhadjustment + dhadj_value) < 0))
- view->drag_info.momentum.x = 0;
- if (((oldvadjustment + dvadj_value) > (v_upper - v_page_size)) ||
- ((oldvadjustment + dvadj_value) < 0))
- view->drag_info.momentum.y = 0;
-
- gtk_adjustment_set_value (view->hadjustment,
- MIN (oldhadjustment + dhadj_value,
- h_upper - h_page_size));
- gtk_adjustment_set_value (view->vadjustment,
- MIN (oldvadjustment + dvadj_value,
- v_upper - v_page_size));
-
- if (((view->drag_info.momentum.x < 1) && (view->drag_info.momentum.x > -1)) &&
- ((view->drag_info.momentum.y < 1) && (view->drag_info.momentum.y > -1)))
- return FALSE;
- else
- return TRUE;
-}
-
-
static void
ev_view_motion_notify_event (GtkEventControllerMotion *self,
gdouble x,
@@ -6111,52 +6181,6 @@ ev_view_motion_notify_event (GtkEventControllerMotion *self,
event->x_root,
event->y_root);
view->drag_info.in_drag = start;
- view->drag_info.drag_timeout_id = g_timeout_add (10,
- (GSourceFunc)ev_view_drag_update_momentum, view);
- /* Set 100 to choose how long it takes to build up momentum */
- /* Clear out previous momentum info: */
- for (i = 0; i < DRAG_HISTORY; i++) {
- view->drag_info.buffer[i].x = event->x;
- view->drag_info.buffer[i].y = event->y;
- }
- view->drag_info.momentum.x = 0;
- view->drag_info.momentum.y = 0;
- }
-
- if (view->drag_info.in_drag) {
- int dx, dy;
- gdouble dhadj_value, dvadj_value;
- GtkAllocation allocation;
-
- view->drag_info.buffer[0].x = x;
- view->drag_info.buffer[0].y = y;
-
- dx = event->x_root - view->drag_info.start.x;
- dy = event->y_root - view->drag_info.start.y;
-
- gtk_widget_get_allocation (widget, &allocation);
-
- dhadj_value = gtk_adjustment_get_page_size (view->hadjustment) *
- (gdouble)dx / allocation.width;
- dvadj_value = gtk_adjustment_get_page_size (view->vadjustment) *
- (gdouble)dy / allocation.height;
-
- /* We will update the drag event's start position if
- * the adjustment value is changed, but only if the
- * change was not caused by this function. */
- view->drag_info.in_notify = TRUE;
-
- /* clamp scrolling to visible area */
- gtk_adjustment_set_value (view->hadjustment,
- MIN (view->drag_info.hadj - dhadj_value,
- gtk_adjustment_get_upper (view->hadjustment) -
- gtk_adjustment_get_page_size (view->hadjustment)));
- gtk_adjustment_set_value (view->vadjustment,
- MIN (view->drag_info.vadj - dvadj_value,
- gtk_adjustment_get_upper (view->vadjustment) -
- gtk_adjustment_get_page_size (view->vadjustment)));
-
- view->drag_info.in_notify = FALSE;
}
#endif
break;
@@ -6307,12 +6331,6 @@ ev_view_button_release_event(GtkGestureClick *self,
return;
}
- if (view->drag_info.in_drag) {
- view->drag_info.release_timeout_id =
- g_timeout_add (20,
- (GSourceFunc)ev_view_scroll_drag_release, view);
- }
-
if (view->document && !view->drag_info.in_drag &&
(view->pressed_button == GDK_BUTTON_PRIMARY ||
view->pressed_button == GDK_BUTTON_MIDDLE)) {
@@ -8424,6 +8442,17 @@ ev_view_init (EvView *view)
G_CALLBACK (zoom_gesture_scale_changed_cb), view);
gtk_widget_add_controller(widget, view->zoom_gesture);
+
+
+ controller = GTK_EVENT_CONTROLLER (gtk_gesture_drag_new ());
+ gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (controller), GDK_BUTTON_MIDDLE);
+ g_signal_connect (controller, "drag-update",
+ G_CALLBACK (on_middle_clicked_drag_update), view);
+ g_signal_connect (controller, "drag-begin",
+ G_CALLBACK (on_middle_clicked_drag_begin), view);
+ g_signal_connect (controller, "drag-end",
+ G_CALLBACK (on_middle_clicked_drag_end), view);
+ gtk_widget_add_controller (widget, controller);
}
/*** Callbacks ***/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]