]> www.fi.muni.cz Git - evince.git/blobdiff - shell/ev-view.c
Updated Bulgarian translation by Vladimir Petkov <vpetkov@i-space.org>
[evince.git] / shell / ev-view.c
index 450c4d455031e70b1bc0c0a4ec98f0a966c766e2..cf60e36b9e0b7969d42076e4c3244e5f74142577 100644 (file)
@@ -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;