Merge lp:~bratsche/oif/evince-move-gestures-into-view into lp:~oif-team/oif/evince-gestures-trunk

Proposed by Cody Russell on 2011-01-06
Status: Merged
Merged at revision: 4212
Proposed branch: lp:~bratsche/oif/evince-move-gestures-into-view
Merge into: lp:~oif-team/oif/evince-gestures-trunk
Diff against target: 580 lines (+237/-164)
6 files modified
configure.ac (+4/-2)
libview/ev-view-private.h (+8/-0)
libview/ev-view.c (+222/-2)
libview/ev-view.h (+1/-1)
previewer/ev-previewer-window.c (+1/-1)
shell/ev-window.c (+1/-158)
To merge this branch: bzr merge lp:~bratsche/oif/evince-move-gestures-into-view
Reviewer Review Type Date Requested Status
Stephen M. Webb (community) 2011-01-06 Approve on 2011-01-07
Review via email: mp+45429@code.launchpad.net

This proposal supersedes a proposal from 2010-12-10.

Description of the change

This branch requires the following first:

https://code.launchpad.net/~bratsche/libgrip/event-routing/+merge/43378

This moves the gesture logic out of EvWindow and into EvView, as well as simply updating evince to work with the libgrip changes in the other merge request.

To post a comment you must log in.
Stephen M. Webb (bregma) wrote :

Please use symbolic constants for threshold values (eg. "drag->velocity_y >= 1.0", "rotate->angle >= 1.0", etc) to (a) make the code more self-documenting and (2) make it easier to find the values to tweak later during the tweak phase.

Other than that, this code looks good. I am unable to build it at the moment to do run-time evaluation.

review: Needs Fixing
4213. By Cody Russell on 2011-01-07

Set some #define constants for velocity and angle.

Cody Russell (bratsche) wrote :

Cool, thanks. Added some #define constants for drag velocity and rotate angle.

Stephen M. Webb (bregma) wrote :

That looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'configure.ac'
2--- configure.ac 2010-11-23 14:39:57 +0000
3+++ configure.ac 2011-01-07 16:47:27 +0000
4@@ -154,6 +154,8 @@
5 GNOME_ICON_THEME_REQUIRED=2.17.1
6 LIBXML_REQUIRED=2.5.0
7
8+GRIP_REQUIRED=0.1
9+
10 dnl Check dependencies
11
12 # LIB_CFLAGS for helpers and generic widgets. (libdocument, cut-and-paste)
13@@ -165,7 +167,7 @@
14
15
16 PKG_CHECK_MODULES(LIBDOCUMENT, gtk+-$GTK_API_VERSION >= $GTK_REQUIRED gio-2.0 >= $GLIB_REQUIRED)
17-PKG_CHECK_MODULES(LIBVIEW, gtk+-$GTK_API_VERSION >= $GTK_REQUIRED gail$GAIL_API_VERSION >= $GTK_REQUIRED gthread-2.0 gio-2.0 >= $GLIB_REQUIRED)
18+PKG_CHECK_MODULES(LIBVIEW, libgrip-0.1 >= $GRIP_REQUIRED gtk+-$GTK_API_VERSION >= $GTK_REQUIRED gail$GAIL_API_VERSION >= $GTK_REQUIRED gthread-2.0 gio-2.0 >= $GLIB_REQUIRED)
19 PKG_CHECK_MODULES(BACKEND, cairo >= $CAIRO_REQUIRED gtk+-$GTK_API_VERSION >= $GTK_REQUIRED)
20 PKG_CHECK_MODULES(FRONTEND_CORE, gtk+-$GTK_API_VERSION >= $GTK_REQUIRED gthread-2.0 gio-2.0 >= $GLIB_REQUIRED)
21
22@@ -193,7 +195,7 @@
23 ;;
24 esac
25
26-PKG_CHECK_MODULES([SHELL_CORE],[libxml-2.0 >= $LIBXML_REQUIRED libgrip-0.1 >= 0.1 gtk+-$GTK_API_VERSION >= $GTK_REQUIRED gio-2.0 >= $GLIB_REQUIRED gthread-2.0 $SHELL_PLATFORM_PKGS])
27+PKG_CHECK_MODULES([SHELL_CORE],[libxml-2.0 >= $LIBXML_REQUIRED libgrip-0.1 >= $GRIP_REQUIRED gtk+-$GTK_API_VERSION >= $GTK_REQUIRED gio-2.0 >= $GLIB_REQUIRED gthread-2.0 $SHELL_PLATFORM_PKGS])
28
29 # *********
30 # SM client
31
32=== modified file 'libview/ev-view-private.h'
33--- libview/ev-view-private.h 2010-09-15 15:05:36 +0000
34+++ libview/ev-view-private.h 2011-01-07 16:47:27 +0000
35@@ -193,6 +193,14 @@
36
37 /* Accessibility */
38 gboolean a11y_enabled;
39+
40+ /* Gesture state */
41+ gboolean enable_gestures;
42+ gdouble drag_start_x;
43+ gdouble drag_start_y;
44+ gdouble pinch_start_x;
45+ gdouble pinch_start_y;
46+ gdouble pinch_start_radius;
47 };
48
49 struct _EvViewClass {
50
51=== modified file 'libview/ev-view.c'
52--- libview/ev-view.c 2010-11-30 05:18:17 +0000
53+++ libview/ev-view.c 2011-01-07 16:47:27 +0000
54@@ -28,6 +28,8 @@
55 #include <gtk/gtk.h>
56 #include <gdk/gdkkeysyms.h>
57
58+#include <libgrip/gripgesturemanager.h>
59+
60 #include "ev-mapping-list.h"
61 #include "ev-document-forms.h"
62 #include "ev-document-images.h"
63@@ -50,6 +52,11 @@
64 #define EV_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EV_TYPE_VIEW, EvViewClass))
65
66 enum {
67+ PROP_0,
68+ PROP_ENABLE_GESTURES
69+};
70+
71+enum {
72 SIGNAL_BINDING_ACTIVATED,
73 SIGNAL_HANDLE_LINK,
74 SIGNAL_EXTERNAL_LINK,
75@@ -77,6 +84,9 @@
76 #define ZOOM_IN_FACTOR 1.2
77 #define ZOOM_OUT_FACTOR (1.0/ZOOM_IN_FACTOR)
78
79+#define GESTURE_DRAG_VELOCITY 1.0
80+#define GESTURE_ROTATE_ANGLE 1.0
81+
82 #define SCROLL_TIME 150
83
84 /*** Scrolling ***/
85@@ -142,6 +152,14 @@
86 static void hide_annotation_windows (EvView *view,
87 gint page);
88 /*** GtkWidget implementation ***/
89+static void ev_view_get_property (GObject *object,
90+ guint prop_id,
91+ GValue *value,
92+ GParamSpec *param_spec);
93+static void ev_view_set_property (GObject *object,
94+ guint prop_id,
95+ const GValue *value,
96+ GParamSpec *param_spec);
97 static void ev_view_size_request_continuous_dual_page (EvView *view,
98 GtkRequisition *requisition);
99 static void ev_view_size_request_continuous (EvView *view,
100@@ -279,6 +297,12 @@
101 gpointer data);
102 static void ev_view_update_primary_selection (EvView *ev_view);
103
104+/*** Gestures ***/
105+static void ev_gesture_callback (GtkWidget *widget,
106+ GripTimeType time_type,
107+ GripGestureEvent *event,
108+ gpointer user_data);
109+
110 G_DEFINE_TYPE (EvView, ev_view, GTK_TYPE_LAYOUT)
111
112 /* HeightToPage cache */
113@@ -2976,6 +3000,114 @@
114 return FALSE;
115 }
116
117+/*** Gesture implementation ***/
118+static void
119+ev_gesture_callback (GtkWidget *widget,
120+ GripTimeType time_type,
121+ GripGestureEvent *event,
122+ gpointer user_data)
123+{
124+ EvView *view = EV_VIEW (widget);
125+
126+ if (time_type == GRIP_TIME_START) {
127+ switch (event->type) {
128+ case GRIP_GESTURE_DRAG: {
129+ GripEventGestureDrag *drag = (GripEventGestureDrag *)event;
130+
131+ view->drag_start_x = drag->position_x;
132+ view->drag_start_y = drag->position_y;
133+
134+ break;
135+ }
136+
137+ case GRIP_GESTURE_PINCH: {
138+ GripEventGesturePinch *pinch = (GripEventGesturePinch *)event;
139+
140+ view->pinch_start_x = pinch->focus_x;
141+ view->pinch_start_y = pinch->focus_y;
142+ view->pinch_start_radius = pinch->radius;
143+ break;
144+ }
145+
146+ default:
147+ break;
148+ }
149+ } else if (time_type == GRIP_TIME_END) {
150+ switch (event->type) {
151+ case GRIP_GESTURE_DRAG: {
152+ GripEventGestureDrag *drag = (GripEventGestureDrag *)event;
153+
154+ if (drag->velocity_y >= GESTURE_DRAG_VELOCITY &&
155+ drag->position_y > view->drag_start_y) {
156+ ev_view_previous_page (view);
157+ } else if (drag->velocity_y <= -GESTURE_DRAG_VELOCITY &&
158+ drag->position_y < view->drag_start_y) {
159+ ev_view_next_page (view);
160+ } else if (drag->velocity_x >= GESTURE_DRAG_VELOCITY &&
161+ drag->position_x > view->drag_start_x) {
162+ ev_view_previous_page (view);
163+ } else if (drag->velocity_x <= -GESTURE_DRAG_VELOCITY &&
164+ drag->position_x < view->drag_start_x) {
165+ ev_view_next_page (view);
166+ }
167+
168+ break;
169+ }
170+
171+ case GRIP_GESTURE_ROTATE: {
172+ GripEventGestureRotate *rotate = (GripEventGestureRotate *)event;
173+ gint rotation = ev_document_model_get_rotation (view->model);
174+
175+ if (rotate->angle >= GESTURE_ROTATE_ANGLE) {
176+ ev_document_model_set_rotation (view->model,
177+ rotation + 90);
178+ } else if (rotate->angle <= -GESTURE_ROTATE_ANGLE) {
179+ ev_document_model_set_rotation (view->model,
180+ rotation - 90);
181+ }
182+
183+ break;
184+ }
185+
186+ default:
187+ break;
188+ }
189+ } else {
190+ switch (event->type) {
191+ case GRIP_GESTURE_PINCH: {
192+ GripEventGesturePinch *pinch = (GripEventGesturePinch *)event;
193+ gdouble increment = pinch->radius_delta * 0.01;
194+
195+ if (increment < 0.0) increment = -increment;
196+ increment += 1.0;
197+
198+ if (pinch->radius_delta < 0.0) {
199+ ev_document_model_set_sizing_mode (view->model, EV_SIZING_FREE);
200+ ev_view_zoom_out_smooth (view, (1.0 / increment));
201+ } else if (pinch->radius_delta > 0.0) {
202+ ev_document_model_set_sizing_mode (view->model, EV_SIZING_FREE);
203+ ev_view_zoom_in_smooth (view, increment);
204+ }
205+
206+ break;
207+ }
208+
209+ case GRIP_GESTURE_DRAG: {
210+ GripEventGestureDrag *drag = (GripEventGestureDrag *)event;
211+
212+ if (drag->fingers == 1) {
213+ ev_view_drag (view,
214+ (gdouble)-drag->delta_x,
215+ (gdouble)-drag->delta_y);
216+ }
217+ }
218+
219+ default:
220+ break;
221+ }
222+ }
223+}
224+
225 /*** GtkWidget implementation ***/
226
227 static void
228@@ -4622,6 +4754,80 @@
229 }
230
231 static void
232+ev_view_get_property (GObject *object,
233+ guint prop_id,
234+ GValue *value,
235+ GParamSpec *param_spec)
236+{
237+ EvView *view = EV_VIEW (object);
238+
239+ switch (prop_id) {
240+ case PROP_ENABLE_GESTURES:
241+ g_value_set_boolean (value, view->enable_gestures);
242+ break;
243+
244+ default:
245+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
246+ prop_id,
247+ param_spec);
248+ }
249+}
250+
251+static void
252+ev_view_set_property (GObject *object,
253+ guint prop_id,
254+ const GValue *value,
255+ GParamSpec *param_spec)
256+{
257+ EvView *view = EV_VIEW (object);
258+ GtkWidget *widget;
259+ GripGestureManager *manager;
260+
261+ switch (prop_id) {
262+ case PROP_ENABLE_GESTURES:
263+ view->enable_gestures = g_value_get_boolean (value);
264+
265+ widget = GTK_WIDGET (view);
266+ manager = grip_gesture_manager_get ();
267+
268+ grip_gesture_manager_register_window (manager,
269+ widget,
270+ GRIP_GESTURE_PINCH,
271+ 2,
272+ ev_gesture_callback,
273+ NULL, NULL);
274+
275+ grip_gesture_manager_register_window (manager,
276+ widget,
277+ GRIP_GESTURE_DRAG,
278+ 2,
279+ ev_gesture_callback,
280+ NULL, NULL);
281+
282+ grip_gesture_manager_register_window (manager,
283+ widget,
284+ GRIP_GESTURE_DRAG,
285+ 1,
286+ ev_gesture_callback,
287+ NULL, NULL);
288+
289+ grip_gesture_manager_register_window (manager,
290+ widget,
291+ GRIP_GESTURE_ROTATE,
292+ 2,
293+ ev_gesture_callback,
294+ NULL, NULL);
295+
296+ break;
297+
298+ default:
299+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
300+ prop_id,
301+ param_spec);
302+ }
303+}
304+
305+static void
306 ev_view_class_init (EvViewClass *class)
307 {
308 GObjectClass *object_class = G_OBJECT_CLASS (class);
309@@ -4631,6 +4837,8 @@
310 GtkBindingSet *binding_set;
311
312 object_class->finalize = ev_view_finalize;
313+ object_class->get_property = ev_view_get_property;
314+ object_class->set_property = ev_view_set_property;
315
316 widget_class->expose_event = ev_view_expose_event;
317 widget_class->button_press_event = ev_view_button_press_event;
318@@ -4724,6 +4932,15 @@
319 G_TYPE_NONE, 0,
320 G_TYPE_NONE);
321
322+ g_object_class_install_property (object_class,
323+ PROP_ENABLE_GESTURES,
324+ g_param_spec_boolean ("enable-gestures",
325+ "Enable gestures",
326+ "Whether to enable gestures",
327+ FALSE,
328+ G_PARAM_WRITABLE |
329+ G_PARAM_CONSTRUCT_ONLY));
330+
331 binding_set = gtk_binding_set_by_class (class);
332
333 add_scroll_binding_keypad (binding_set, GDK_Left, 0, GTK_SCROLL_STEP_BACKWARD, TRUE);
334@@ -4775,6 +4992,7 @@
335 gtk_layout_set_vadjustment (GTK_LAYOUT (view), NULL);
336 }
337
338+
339 /*** Callbacks ***/
340
341 static void
342@@ -4911,11 +5129,13 @@
343 }
344
345 GtkWidget*
346-ev_view_new (void)
347+ev_view_new (gboolean enable_gestures)
348 {
349 GtkWidget *view;
350
351- view = g_object_new (EV_TYPE_VIEW, NULL);
352+ view = g_object_new (EV_TYPE_VIEW,
353+ "enable-gestures", enable_gestures,
354+ NULL);
355
356 return view;
357 }
358
359=== modified file 'libview/ev-view.h'
360--- libview/ev-view.h 2010-11-30 05:18:17 +0000
361+++ libview/ev-view.h 2011-01-07 16:47:27 +0000
362@@ -46,7 +46,7 @@
363
364 GType ev_view_get_type (void) G_GNUC_CONST;
365
366-GtkWidget* ev_view_new (void);
367+GtkWidget* ev_view_new (gboolean enable_gestures);
368 void ev_view_set_model (EvView *view,
369 EvDocumentModel *model);
370 void ev_view_set_loading (EvView *view,
371
372=== modified file 'previewer/ev-previewer-window.c'
373--- previewer/ev-previewer-window.c 2010-07-26 13:34:18 +0000
374+++ previewer/ev-previewer-window.c 2011-01-07 16:47:27 +0000
375@@ -607,7 +607,7 @@
376 GTK_POLICY_AUTOMATIC,
377 GTK_POLICY_AUTOMATIC);
378
379- window->view = EV_VIEW (ev_view_new ());
380+ window->view = EV_VIEW (ev_view_new (FALSE));
381 g_signal_connect_object (window->view, "focus_in_event",
382 G_CALLBACK (view_focus_changed),
383 window, 0);
384
385=== modified file 'shell/ev-window.c'
386--- shell/ev-window.c 2010-12-07 08:43:18 +0000
387+++ shell/ev-window.c 2011-01-07 16:47:27 +0000
388@@ -41,8 +41,6 @@
389 #include <gio/gio.h>
390 #include <gtk/gtk.h>
391
392-#include <libgrip/gripgesturemanager.h>
393-
394 #include "egg-editable-toolbar.h"
395 #include "egg-toolbar-editor.h"
396 #include "egg-toolbars-model.h"
397@@ -218,13 +216,6 @@
398 guint dbus_object_id;
399 gchar *dbus_object_path;
400 #endif
401-
402- gdouble drag_start_x;
403- gdouble drag_start_y;
404-
405- gdouble pinch_start_x;
406- gdouble pinch_start_y;
407- gdouble pinch_start_radius;
408 };
409
410 #define EV_WINDOW_GET_PRIVATE(object) \
411@@ -5433,151 +5424,6 @@
412 }
413
414 static void
415-ev_gesture_callback (GtkWindow *window,
416- GripTimeType time_type,
417- GripGestureEvent *event,
418- gpointer user_data)
419-{
420- EvWindowPrivate *priv = EV_WINDOW (window)->priv;
421-
422- if (time_type == GRIP_TIME_START) {
423- switch (event->type) {
424- case GRIP_GESTURE_DRAG: {
425- GripEventGestureDrag *drag = (GripEventGestureDrag *)event;
426-
427- priv->drag_start_x = drag->position_x;
428- priv->drag_start_y = drag->position_y;
429-
430- break;
431- }
432-
433- case GRIP_GESTURE_PINCH: {
434- GripEventGesturePinch *pinch = (GripEventGesturePinch *)event;
435-
436- priv->pinch_start_x = pinch->focus_x;
437- priv->pinch_start_y = pinch->focus_y;
438- priv->pinch_start_radius = pinch->radius;
439- break;
440- }
441-
442- default:
443- break;
444- }
445- } else if (time_type == GRIP_TIME_END) {
446- switch (event->type) {
447- case GRIP_GESTURE_DRAG: {
448- GripEventGestureDrag *drag = (GripEventGestureDrag *)event;
449-
450- if (drag->velocity_y >= 1.0 &&
451- drag->position_y > priv->drag_start_y) {
452- ev_window_cmd_go_previous_page (NULL, EV_WINDOW (window));
453- } else if (drag->velocity_y <= -1.0 &&
454- drag->position_y < priv->drag_start_y) {
455- ev_window_cmd_go_next_page (NULL, EV_WINDOW (window));
456- } else if (drag->velocity_x >= 1.0 &&
457- drag->position_x > priv->drag_start_x) {
458- ev_window_cmd_go_previous_page (NULL, EV_WINDOW (window));
459- } else if (drag->velocity_x <= -1.0 &&
460- drag->position_x < priv->drag_start_x) {
461- ev_window_cmd_go_next_page (NULL, EV_WINDOW (window));
462- }
463-
464- break;
465- }
466-
467- case GRIP_GESTURE_ROTATE: {
468- GripEventGestureRotate *rotate = (GripEventGestureRotate *)event;
469-
470- if (rotate->angle >= 1.0) {
471- ev_window_cmd_edit_rotate_right (NULL, EV_WINDOW (window));
472- } else if (rotate->angle <= -1.0) {
473- ev_window_cmd_edit_rotate_left (NULL, EV_WINDOW (window));
474- }
475-
476- break;
477- }
478-
479- default:
480- break;
481- }
482- } else {
483- switch (event->type) {
484- case GRIP_GESTURE_PINCH: {
485- GripEventGesturePinch *pinch = (GripEventGesturePinch *)event;
486- gdouble increment = pinch->radius_delta * 0.01;
487-
488- if (increment < 0.0) increment = -increment;
489- increment += 1.0;
490-
491- if (pinch->radius_delta < 0.0) {
492- ev_document_model_set_sizing_mode (priv->model, EV_SIZING_FREE);
493- ev_view_zoom_out_smooth (EV_VIEW (priv->view), (1.0 / increment));
494- } else if (pinch->radius_delta > 0.0) {
495- ev_document_model_set_sizing_mode (priv->model, EV_SIZING_FREE);
496- ev_view_zoom_in_smooth (EV_VIEW (priv->view), increment);
497- }
498-
499- break;
500- }
501-
502- case GRIP_GESTURE_DRAG: {
503- GripEventGestureDrag *drag = (GripEventGestureDrag *)event;
504-
505- if (drag->fingers == 1) {
506- ev_view_drag (EV_VIEW (priv->view),
507- (gdouble)-drag->delta_x,
508- (gdouble)-drag->delta_y);
509- }
510- }
511-
512- default:
513- break;
514- }
515- }
516-}
517-
518-static void
519-on_window_mapped (GtkWidget *widget)
520-{
521- GtkWindow *window;
522- GripGestureManager *manager;
523-
524- window = GTK_WINDOW (widget);
525-
526- if (ev_application_get_gestures_enabled (EV_APP)) {
527- manager = grip_gesture_manager_get ();
528-
529- grip_gesture_manager_register_window (manager,
530- window,
531- GRIP_GESTURE_PINCH,
532- 2,
533- ev_gesture_callback,
534- NULL, NULL);
535-
536- grip_gesture_manager_register_window (manager,
537- window,
538- GRIP_GESTURE_DRAG,
539- 2,
540- ev_gesture_callback,
541- NULL, NULL);
542-
543- grip_gesture_manager_register_window (manager,
544- window,
545- GRIP_GESTURE_DRAG,
546- 1,
547- ev_gesture_callback,
548- NULL, NULL);
549-
550- grip_gesture_manager_register_window (manager,
551- window,
552- GRIP_GESTURE_ROTATE,
553- 2,
554- ev_gesture_callback,
555- NULL, NULL);
556- }
557-}
558-
559-static void
560 ev_window_class_init (EvWindowClass *ev_window_class)
561 {
562 GObjectClass *g_object_class = G_OBJECT_CLASS (ev_window_class);
563@@ -6914,9 +6760,6 @@
564 g_signal_connect (ev_window, "window_state_event",
565 G_CALLBACK (window_state_event_cb), NULL);
566
567- g_signal_connect (ev_window, "show",
568- G_CALLBACK (on_window_mapped), NULL);
569-
570 ev_window->priv = EV_WINDOW_GET_PRIVATE (ev_window);
571
572 #ifdef ENABLE_DBUS
573@@ -7142,7 +6985,7 @@
574 ev_window->priv->view_box);
575 gtk_widget_show (ev_window->priv->view_box);
576
577- ev_window->priv->view = ev_view_new ();
578+ ev_window->priv->view = ev_view_new (ev_application_get_gestures_enabled (EV_APP));
579 ev_view_set_page_cache_size (EV_VIEW (ev_window->priv->view), PAGE_CACHE_SIZE);
580 ev_view_set_model (EV_VIEW (ev_window->priv->view), ev_window->priv->model);
581

Subscribers

People subscribed via source and target branches