X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=sidebyside;f=shell%2Fev-view.c;h=cf60e36b9e0b7969d42076e4c3244e5f74142577;hb=f7510970589ab3a687023b127803ae6d11d41aca;hp=450c4d455031e70b1bc0c0a4ec98f0a966c766e2;hpb=7a949ef059ba54c25ae74cb56742cda78e059a39;p=evince.git diff --git a/shell/ev-view.c b/shell/ev-view.c index 450c4d45..cf60e36b 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -59,11 +59,6 @@ enum { TARGET_TEXT_BUFFER_CONTENTS }; -enum { - EV_SCROLL_PAGE_FORWARD, - EV_SCROLL_PAGE_BACKWARD -}; - static const GtkTargetEntry targets[] = { { "STRING", 0, TARGET_STRING }, { "TEXT", 0, TARGET_TEXT }, @@ -75,7 +70,8 @@ typedef enum { EV_VIEW_CURSOR_NORMAL, EV_VIEW_CURSOR_LINK, EV_VIEW_CURSOR_WAIT, - EV_VIEW_CURSOR_HIDDEN + EV_VIEW_CURSOR_HIDDEN, + EV_VIEW_CURSOR_DRAG } EvViewCursor; #define ZOOM_IN_FACTOR 1.2 @@ -85,10 +81,17 @@ typedef enum { #define MAX_SCALE 6.0 typedef struct { - EvRectangle rect; - int page; + EvRectangle rect; + int page; } EvViewSelection; +typedef struct { + gboolean dragging; + GdkPoint start; + gdouble hadj; + gdouble vadj; +} DragInfo; + struct _EvView { GtkWidget parent_instance; @@ -102,6 +105,7 @@ struct _EvView { int scroll_x; int scroll_y; + DragInfo drag_info; gboolean pressed_button; GdkPoint selection_start; GList *selections; @@ -900,7 +904,12 @@ highlight_find_results (EvView *view, int page) GdkRectangle view_rectangle; guchar alpha; - alpha = (i == view->find_result) ? 0x90 : 0x20; + if (i == view->find_result && page == view->find_page) { + alpha = 0x90; + } else { + alpha = 0x20; + } + ev_document_find_get_result (find, page, i, &rectangle); doc_rect_to_view_rect (view, page, &rectangle, &view_rectangle); @@ -931,10 +940,6 @@ draw_one_page (EvView *view, page, view->scale, &width, &height); - ev_document_misc_paint_one_page (view->bin_window, - GTK_WIDGET (view), - page_area, border); - /* Render the document itself */ real_page_area = *page_area; @@ -946,7 +951,12 @@ draw_one_page (EvView *view, if (! gdk_rectangle_intersect (&real_page_area, expose_area, &overlap)) return; + ev_document_misc_paint_one_page (view->bin_window, + GTK_WIDGET (view), + page_area, border); + current_pixbuf = ev_pixbuf_cache_get_pixbuf (view->pixbuf_cache, page); + if (current_pixbuf == NULL) scaled_image = NULL; else if (width == gdk_pixbuf_get_width (current_pixbuf) && @@ -956,6 +966,7 @@ draw_one_page (EvView *view, scaled_image = gdk_pixbuf_scale_simple (current_pixbuf, width, height, GDK_INTERP_NEAREST); + if (scaled_image) { gdk_draw_pixbuf (view->bin_window, GTK_WIDGET (view)->style->fg_gc[GTK_STATE_NORMAL], @@ -1140,6 +1151,58 @@ ev_view_update_primary_selection (EvView *ev_view) } } +static GdkCursor * +ev_view_create_invisible_cursor(void) +{ + GdkBitmap *empty; + GdkColor black = { 0, 0, 0, 0 }; + static char bits[] = { 0x00 }; + + empty = gdk_bitmap_create_from_data (NULL, bits, 1, 1); + + return gdk_cursor_new_from_pixmap (empty, empty, &black, &black, 0, 0); +} + +static void +ev_view_set_cursor (EvView *view, EvViewCursor new_cursor) +{ + GdkCursor *cursor = NULL; + GdkDisplay *display; + GtkWidget *widget; + + if (view->cursor == new_cursor) { + return; + } + + widget = gtk_widget_get_toplevel (GTK_WIDGET (view)); + display = gtk_widget_get_display (widget); + view->cursor = new_cursor; + + switch (new_cursor) { + case EV_VIEW_CURSOR_NORMAL: + gdk_window_set_cursor (widget->window, NULL); + break; + case EV_VIEW_CURSOR_LINK: + cursor = gdk_cursor_new_for_display (display, GDK_HAND2); + break; + case EV_VIEW_CURSOR_WAIT: + cursor = gdk_cursor_new_for_display (display, GDK_WATCH); + break; + case EV_VIEW_CURSOR_HIDDEN: + cursor = ev_view_create_invisible_cursor (); + break; + case EV_VIEW_CURSOR_DRAG: + cursor = gdk_cursor_new_for_display (display, GDK_FLEUR); + break; + } + + if (cursor) { + gdk_window_set_cursor (widget->window, cursor); + gdk_cursor_unref (cursor); + gdk_flush(); + } +} + static gboolean ev_view_button_press_event (GtkWidget *widget, GdkEventButton *event) @@ -1161,10 +1224,21 @@ ev_view_button_press_event (GtkWidget *widget, view->selection_start.x = event->x; view->selection_start.y = event->y; - break; + return TRUE; + case 2: + /* 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); + + return TRUE; } - return TRUE; + return FALSE; } static char * @@ -1218,57 +1292,6 @@ ev_view_set_find_status (EvView *view, const char *message) g_object_notify (G_OBJECT (view), "find-status"); } -static GdkCursor * -ev_view_create_invisible_cursor(void) -{ - GdkBitmap *empty; - GdkColor black = { 0, 0, 0, 0 }; - static char bits[] = { 0x00 }; - - empty = gdk_bitmap_create_from_data (NULL, bits, 1, 1); - - return gdk_cursor_new_from_pixmap (empty, empty, &black, &black, 0, 0); -} - -static void -ev_view_set_cursor (EvView *view, EvViewCursor new_cursor) -{ - GdkCursor *cursor = NULL; - GdkDisplay *display; - GtkWidget *widget; - - if (view->cursor == new_cursor) { - return; - } - - widget = gtk_widget_get_toplevel (GTK_WIDGET (view)); - display = gtk_widget_get_display (widget); - view->cursor = new_cursor; - - switch (new_cursor) { - case EV_VIEW_CURSOR_NORMAL: - gdk_window_set_cursor (widget->window, NULL); - break; - case EV_VIEW_CURSOR_LINK: - cursor = gdk_cursor_new_for_display (display, GDK_HAND2); - break; - case EV_VIEW_CURSOR_WAIT: - cursor = gdk_cursor_new_for_display (display, GDK_WATCH); - break; - case EV_VIEW_CURSOR_HIDDEN: - cursor = ev_view_create_invisible_cursor (); - break; - - } - - if (cursor) { - gdk_window_set_cursor (widget->window, cursor); - gdk_cursor_unref (cursor); - gdk_flush(); - } -} - - static void find_page_at_location (EvView *view, gdouble x, @@ -1336,7 +1359,7 @@ ev_view_motion_notify_event (GtkWidget *widget, { EvView *view = EV_VIEW (widget); - if (view->pressed_button > 0) { + if (view->pressed_button == 1) { GdkRectangle selection; selection.x = MIN (view->selection_start.x, event->x); @@ -1347,7 +1370,45 @@ ev_view_motion_notify_event (GtkWidget *widget, compute_selections (view, &selection); gtk_widget_queue_draw (widget); - } else if (view->document) { + + return TRUE; + } else if (view->pressed_button == 2) { + if (!view->drag_info.dragging) { + gboolean start; + + start = gtk_drag_check_threshold (widget, + view->drag_info.start.x, + view->drag_info.start.y, + event->x_root, + event->y_root); + view->drag_info.dragging = start; + } + + if (view->drag_info.dragging) { + int dx, dy; + gdouble dhadj_value, dvadj_value; + + dx = event->x_root - view->drag_info.start.x; + dy = event->y_root - view->drag_info.start.y; + + dhadj_value = view->hadjustment->page_size * + (gdouble)dx / widget->allocation.width; + dvadj_value = view->vadjustment->page_size * + (gdouble)dy / widget->allocation.height; + + /* clamp scrolling to visible area */ + gtk_adjustment_set_value (view->hadjustment, + MIN(view->drag_info.hadj - dhadj_value, + view->hadjustment->upper - + view->hadjustment->page_size)); + gtk_adjustment_set_value (view->vadjustment, + MIN(view->drag_info.vadj - dvadj_value, + view->vadjustment->upper - + view->vadjustment->page_size)); + + return TRUE; + } + } else if (view->pressed_button <= 0 && view->document) { EvLink *link; link = get_link_at_location (view, event->x, event->y); @@ -1364,9 +1425,10 @@ ev_view_motion_notify_event (GtkWidget *widget, ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL); } } + return TRUE; } - return TRUE; + return FALSE; } /* FIXME: standardize this sometime */ @@ -1400,7 +1462,12 @@ ev_view_button_release_event (GtkWidget *widget, { EvView *view = EV_VIEW (widget); + if (view->pressed_button == 2) { + ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL); + } + view->pressed_button = -1; + view->drag_info.dragging = FALSE; if (view->selections) { ev_view_update_primary_selection (view); @@ -1483,26 +1550,9 @@ add_scroll_binding_keypad (GtkBindingSet *binding_set, G_TYPE_BOOLEAN, horizontal); } -static void -add_scroll_binding_shifted (GtkBindingSet *binding_set, - guint keyval, - GtkScrollType scroll_normal, - GtkScrollType scroll_shifted, - gboolean horizontal) -{ - gtk_binding_entry_add_signal (binding_set, keyval, 0, - "scroll_view", 2, - GTK_TYPE_SCROLL_TYPE, scroll_normal, - G_TYPE_BOOLEAN, horizontal); - gtk_binding_entry_add_signal (binding_set, keyval, GDK_SHIFT_MASK, - "scroll_view", 2, - GTK_TYPE_SCROLL_TYPE, scroll_shifted, - G_TYPE_BOOLEAN, horizontal); -} - -static void -ev_view_jump (EvView *view, - GtkScrollType scroll) +void +ev_view_scroll (EvView *view, + EvScrollType scroll) { GtkAdjustment *adjustment; double value, increment; @@ -1563,8 +1613,6 @@ ev_view_scroll_view (EvView *view, ev_page_cache_prev_page (view->page_cache); } else if (scroll == GTK_SCROLL_PAGE_FORWARD) { ev_page_cache_next_page (view->page_cache); - } else if (scroll == EV_SCROLL_PAGE_BACKWARD || scroll == EV_SCROLL_PAGE_FORWARD) { - ev_view_jump (view, scroll); } else { GtkAdjustment *adjustment; double value; @@ -1771,9 +1819,6 @@ ev_view_class_init (EvViewClass *class) add_scroll_binding_keypad (binding_set, GDK_Page_Up, GTK_SCROLL_PAGE_BACKWARD, FALSE); add_scroll_binding_keypad (binding_set, GDK_Page_Down, GTK_SCROLL_PAGE_FORWARD, FALSE); - - add_scroll_binding_shifted (binding_set, GDK_space, EV_SCROLL_PAGE_FORWARD, EV_SCROLL_PAGE_BACKWARD, FALSE); - add_scroll_binding_shifted (binding_set, GDK_BackSpace, EV_SCROLL_PAGE_BACKWARD, EV_SCROLL_PAGE_FORWARD, FALSE); } static void @@ -1786,6 +1831,7 @@ ev_view_init (EvView *view) view->current_page = 0; view->pressed_button = -1; view->cursor = EV_VIEW_CURSOR_NORMAL; + view->drag_info.dragging = FALSE; view->continuous = TRUE; view->dual_page = FALSE;