From 14633f07b92d515ca0c4447506fa938b3568f013 Mon Sep 17 00:00:00 2001 From: Nickolay V. Shmyrev Date: Sun, 23 Dec 2007 17:14:04 +0000 Subject: Autoscroll feature with the context menu. Fixes bug #323670. Thanks to 2007-12-23 Nickolay V. Shmyrev * data/evince-toolbar.xml: * data/evince-ui.xml: * shell/ev-view-private.h: * shell/ev-view.c: (ev_view_handle_cursor_over_xy), (ev_view_button_press_event), (ev_view_motion_notify_event), (ev_view_button_release_event), (ev_view_init), (ev_view_autoscroll_cb), (ev_view_autoscroll), (ev_view_set_cursor): * shell/ev-view.h: * shell/ev-window.c: (ev_window_setup_action_sensitivity), (ev_window_cmd_view_autoscroll): Autoscroll feature with the context menu. Fixes bug #323670. Thanks to David Turner . svn path=/trunk/; revision=2781 --- diff --git a/ChangeLog b/ChangeLog index 5e494b3..6561210 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2007-12-23 Nickolay V. Shmyrev + + * data/evince-toolbar.xml: + * data/evince-ui.xml: + * shell/ev-view-private.h: + * shell/ev-view.c: (ev_view_handle_cursor_over_xy), + (ev_view_button_press_event), (ev_view_motion_notify_event), + (ev_view_button_release_event), (ev_view_init), + (ev_view_autoscroll_cb), (ev_view_autoscroll), + (ev_view_set_cursor): + * shell/ev-view.h: + * shell/ev-window.c: (ev_window_setup_action_sensitivity), + (ev_window_cmd_view_autoscroll): + + Autoscroll feature with the context menu. Fixes bug + #323670. Thanks to David Turner . + 2007-12-23 Carlos Garcia Campos * shell/ev-pixbuf-cache.c: (check_job_size_and_unref): @@ -5,7 +22,7 @@ Disconnect also page-ready signal when removing a job because the page size has changed. Thanks to kripken . - + 2007-12-21 Nickolay V. Shmyrev * shell/ev-page-action.c: (page_scroll_cb), (create_tool_item): diff --git a/data/evince-toolbar.xml b/data/evince-toolbar.xml index 5321571..d8073ec 100644 --- a/data/evince-toolbar.xml +++ b/data/evince-toolbar.xml @@ -6,6 +6,7 @@ + diff --git a/data/evince-ui.xml b/data/evince-ui.xml index f85bd42..93e4438 100644 --- a/data/evince-ui.xml +++ b/data/evince-ui.xml @@ -70,6 +70,7 @@ + diff --git a/shell/ev-view-private.h b/shell/ev-view-private.h index e839a31..22bd7a0 100644 --- a/shell/ev-view-private.h +++ b/shell/ev-view-private.h @@ -36,6 +36,14 @@ typedef struct { gdouble vadj; } DragInfo; +/* Autoscrolling */ +typedef struct { + gboolean autoscrolling; + guint last_y; + guint start_y; + guint timeout_id; +} AutoScrollInfo; + /* Information for handling selection */ typedef struct { gboolean in_drag; @@ -65,7 +73,8 @@ typedef enum { EV_VIEW_CURSOR_LINK, EV_VIEW_CURSOR_WAIT, EV_VIEW_CURSOR_HIDDEN, - EV_VIEW_CURSOR_DRAG + EV_VIEW_CURSOR_DRAG, + EV_VIEW_CURSOR_AUTOSCROLL, } EvViewCursor; typedef enum { @@ -133,6 +142,9 @@ struct _EvView { /* Information for middle clicking and dragging around. */ DragInfo drag_info; + + /* Autoscrolling */ + AutoScrollInfo scroll_info; /* Selection */ GdkPoint motion; diff --git a/shell/ev-view.c b/shell/ev-view.c index bbfeecf..c4baa7c 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -1521,6 +1521,12 @@ ev_view_handle_cursor_over_xy (EvView *view, gint x, gint y) ev_view_set_cursor (view, EV_VIEW_CURSOR_DRAG); return; } + + if (view->scroll_info.autoscrolling) { + if (view->cursor != EV_VIEW_CURSOR_AUTOSCROLL) + ev_view_set_cursor (view, EV_VIEW_CURSOR_AUTOSCROLL); + return; + } link = ev_view_get_link_at_location (view, x, y); @@ -2663,6 +2669,12 @@ ev_view_button_press_event (GtkWidget *widget, switch (event->button) { case 1: { + + if (view->scroll_info.autoscrolling == TRUE) { + view->scroll_info.autoscrolling = FALSE; + return TRUE; + } + EvImage *image; EvFormField *field; @@ -2701,6 +2713,10 @@ ev_view_button_press_event (GtkWidget *widget, case 2: /* use root coordinates as reference point because * scrolling changes window relative coordinates */ + if (view->scroll_info.autoscrolling == TRUE) { + view->scroll_info.autoscrolling = FALSE; + return TRUE; + } 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); @@ -2710,6 +2726,8 @@ ev_view_button_press_event (GtkWidget *widget, return TRUE; case 3: + if (!view->scroll_info.autoscrolling) + view->scroll_info.start_y = event->y; return ev_view_do_popup_menu (view, event->x, event->y); } @@ -2883,6 +2901,7 @@ ev_view_motion_notify_event (GtkWidget *widget, if (!view->document) return FALSE; + if (event->is_hint || event->window != view->layout.bin_window) { gtk_widget_get_pointer (widget, &x, &y); @@ -2891,6 +2910,10 @@ ev_view_motion_notify_event (GtkWidget *widget, y = event->y; } + if (view->scroll_info.autoscrolling) { + view->scroll_info.last_y = y; + } + if (view->selection_info.in_drag) { if (gtk_drag_check_threshold (widget, view->selection_info.start.x, @@ -3025,6 +3048,10 @@ ev_view_button_release_event (GtkWidget *widget, g_source_remove (view->selection_scroll_id); view->selection_scroll_id = 0; } + if (view->scroll_info.timeout_id) { + g_source_remove (view->scroll_info.timeout_id); + view->scroll_info.timeout_id = 0; + } if (view->selection_update_id) { g_source_remove (view->selection_update_id); view->selection_update_id = 0; @@ -4042,6 +4069,7 @@ ev_view_init (EvView *view) view->pressed_button = -1; view->cursor = EV_VIEW_CURSOR_NORMAL; view->drag_info.in_drag = FALSE; + view->scroll_info.autoscrolling = FALSE; view->selection_info.selections = NULL; view->selection_info.in_selection = FALSE; view->selection_info.in_drag = FALSE; @@ -4222,6 +4250,45 @@ ev_view_set_loading (EvView *view, gtk_widget_queue_draw (GTK_WIDGET (view)); } +static gboolean ev_view_autoscroll_cb (EvView *view) +{ + gdouble speed, value; + + /* If the user stops autoscrolling, autoscrolling will be + * set to false but the timeout will continue; stop the timeout: */ + if (!view->scroll_info.autoscrolling) { + view->scroll_info.timeout_id = 0; + return FALSE; + } + + if (view->scroll_info.last_y > view->scroll_info.start_y && + (view->scroll_info.last_y < view->scroll_info.start_y)) + return TRUE; + + /* Replace 100 with your speed of choice: The lower the faster. + * Replace 3 with another speed of choice: The higher, the faster it accelerated + * based on the distance of the starting point from the mouse + * (All also effected by the timeout interval of this callback) */ + + if (view->scroll_info.start_y > view->scroll_info.last_y) + speed = -pow ((((gdouble)view->scroll_info.start_y - view->scroll_info.last_y) / 100), 3); + else + speed = pow ((((gdouble)view->scroll_info.last_y - view->scroll_info.start_y) / 100), 3); + + value = gtk_adjustment_get_value (view->vadjustment); + value = CLAMP (value + speed, 0, view->vadjustment->upper - view->vadjustment->page_size); + gtk_adjustment_set_value (view->vadjustment, value); + + return TRUE; + +} + +void ev_view_autoscroll(EvView *view) +{ + view->scroll_info.autoscrolling = TRUE; + view->scroll_info.timeout_id = g_timeout_add (20, (GSourceFunc)(ev_view_autoscroll_cb), view); +} + void ev_view_set_document (EvView *view, EvDocument *document) @@ -5563,6 +5630,9 @@ ev_view_set_cursor (EvView *view, EvViewCursor new_cursor) case EV_VIEW_CURSOR_DRAG: cursor = gdk_cursor_new_for_display (display, GDK_FLEUR); break; + case EV_VIEW_CURSOR_AUTOSCROLL: + cursor = gdk_cursor_new_for_display (display, GDK_DOUBLE_ARROW); + break; } if (cursor) { diff --git a/shell/ev-view.h b/shell/ev-view.h index 667b2ee..784f797 100644 --- a/shell/ev-view.h +++ b/shell/ev-view.h @@ -73,7 +73,6 @@ void ev_view_set_document (EvView *view, EvDocument *document); void ev_view_set_loading (EvView *view, gboolean loading); - /* Clipboard */ void ev_view_copy (EvView *view); void ev_view_select_all (EvView *view); @@ -145,6 +144,8 @@ gchar* ev_view_page_label_from_dest (EvView *view, EvLinkDest *dest); void ev_view_update_view_size (EvView *view, GtkScrolledWindow *scrolled_window); +void ev_view_autoscroll (EvView *view); + G_END_DECLS #endif /* __EV_VIEW_H__ */ diff --git a/shell/ev-window.c b/shell/ev-window.c index ca2a14e..bbf9d46 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -393,6 +393,7 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) ev_window_set_action_sensitive (ev_window, "ViewBestFit", has_pages); ev_window_set_action_sensitive (ev_window, "ViewPageWidth", has_pages); ev_window_set_action_sensitive (ev_window, "ViewReload", has_pages); + ev_window_set_action_sensitive (ev_window, "ViewAutoscroll", has_pages); /* Toolbar-specific actions: */ ev_window_set_action_sensitive (ev_window, PAGE_SELECTOR_ACTION, has_pages); @@ -3359,6 +3360,12 @@ ev_window_cmd_view_reload (GtkAction *action, EvWindow *ev_window) } static void +ev_window_cmd_view_autoscroll (GtkAction *action, EvWindow *ev_window) +{ + ev_view_autoscroll (EV_VIEW (ev_window->priv->view)); +} + +static void ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window) { GError *error = NULL; @@ -4399,6 +4406,9 @@ static const GtkActionEntry entries[] = { N_("Reload the document"), G_CALLBACK (ev_window_cmd_view_reload) }, + { "ViewAutoscroll", GTK_STOCK_MEDIA_PLAY, N_("Auto_scroll"), NULL, NULL, + G_CALLBACK (ev_window_cmd_view_autoscroll) }, + /* Go menu */ { "GoPreviousPage", GTK_STOCK_GO_BACK, N_("_Previous Page"), "Page_Up", N_("Go to the previous page"), -- cgit v0.9.1