diff options
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ev-view-private.h | 14 | ||||
-rw-r--r-- | shell/ev-view.c | 70 | ||||
-rw-r--r-- | shell/ev-view.h | 3 | ||||
-rw-r--r-- | shell/ev-window.c | 10 |
4 files changed, 95 insertions, 2 deletions
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"), "<control>Page_Up", N_("Go to the previous page"), |