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=45f5de07fa748735d73f27c87e853b0be867ffe7;hb=b69134d4ad94bcf59ce305d62088487dbb7e727e;hp=3da8d138fed932334dc6f52eb2786c79c60a0d92;hpb=80a9ffebfe5125584341d4fb005ee1a29219c970;p=evince.git diff --git a/shell/ev-view.c b/shell/ev-view.c index 3da8d138..45f5de07 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -49,6 +49,7 @@ enum { PROP_FULLSCREEN, PROP_PRESENTATION, PROP_SIZING_MODE, + PROP_ZOOM, }; enum { @@ -86,7 +87,7 @@ typedef enum { #define ZOOM_OUT_FACTOR (1.0/ZOOM_IN_FACTOR) #define MIN_SCALE 0.05409 -#define MAX_SCALE 6.0 +#define MAX_SCALE 4.0 typedef struct { EvRectangle rect; @@ -114,8 +115,8 @@ struct _EvView { char *status; char *find_status; - int scroll_x; - int scroll_y; + gint scroll_x; + gint scroll_y; DragInfo drag_info; gboolean pressed_button; @@ -149,6 +150,7 @@ struct _EvView { EvSizingMode sizing_mode; PendingScroll pending_scroll; + gboolean pending_resize; }; struct _EvViewClass { @@ -164,13 +166,10 @@ struct _EvViewClass { }; /*** Scrolling ***/ -static void view_update_adjustments (EvView *view); static void ev_view_set_scroll_adjustments (EvView *view, GtkAdjustment *hadjustment, GtkAdjustment *vadjustment); static void view_update_range_and_current_page (EvView *view); -static void view_scroll_to_page (EvView *view, - gint new_page); static void set_scroll_adjustment (EvView *view, GtkOrientation orientation, GtkAdjustment *adjustment); @@ -356,33 +355,45 @@ static void ev_view_update_primary_selection (EvView G_DEFINE_TYPE (EvView, ev_view, GTK_TYPE_WIDGET) static void -view_update_adjustments (EvView *view) +scroll_to_current_page (EvView *view, GtkOrientation orientation) { - int dx = 0, dy = 0; - - if (! GTK_WIDGET_REALIZED (view)) - return; - - if (view->hadjustment) { - dx = view->scroll_x - view->hadjustment->value; - view->scroll_x = view->hadjustment->value; - } else { - view->scroll_x = 0; - } - - if (view->vadjustment) { - dy = view->scroll_y - view->vadjustment->value; - view->scroll_y = view->vadjustment->value; + int max_width, max_height, n_rows; + + get_bounding_box_size (view, &max_width, &max_height); + + if (orientation == GTK_ORIENTATION_VERTICAL) { + if (view->continuous) { + n_rows = view->dual_page ? view->current_page / 2 : view->current_page; + + gtk_adjustment_clamp_page (view->vadjustment, + (max_height + view->spacing) * n_rows, + (max_height + view->spacing) * n_rows + + view->vadjustment->page_size); + } else { + gtk_adjustment_set_value (view->vadjustment, + view->vadjustment->lower); + } } else { - view->scroll_y = 0; + if (view->dual_page) { + if (view->current_page % 2 == 0) { + gtk_adjustment_set_value (view->hadjustment, + view->hadjustment->lower); + } else { + gtk_adjustment_clamp_page (view->hadjustment, + view->hadjustment->lower + + max_width + view->spacing, + view->hadjustment->lower + + max_width + view->spacing + + view->hadjustment->page_size); + } + } else { + gtk_adjustment_set_value (view->hadjustment, + CLAMP (view->hadjustment->value, + view->hadjustment->lower, + view->hadjustment->upper - + view->hadjustment->page_size)); + } } - - // gtk_widget_queue_draw (GTK_WIDGET (view)); - gdk_window_scroll (GTK_WIDGET (view)->window, dx, dy); - - - if (view->document) - view_update_range_and_current_page (view); } static void @@ -431,16 +442,15 @@ view_set_adjustment_values (EvView *view, switch (view->pending_scroll) { case SCROLL_TO_KEEP_POSITION: new_value = CLAMP (adjustment->upper * factor, 0, adjustment->upper - adjustment->page_size); - gtk_adjustment_set_value (adjustment, new_value); + gtk_adjustment_set_value (adjustment, (int)new_value); break; case SCROLL_TO_CURRENT_PAGE: - if (orientation == GTK_ORIENTATION_VERTICAL) { - view_scroll_to_page (view, view->current_page); - } + scroll_to_current_page (view, orientation); break; case SCROLL_TO_CENTER: - new_value = CLAMP (adjustment->upper * factor - adjustment->page_size * 0.5, 0, adjustment->upper - adjustment->page_size); - gtk_adjustment_set_value (adjustment, new_value); + new_value = CLAMP (adjustment->upper * factor - adjustment->page_size * 0.5, + 0, adjustment->upper - adjustment->page_size); + gtk_adjustment_set_value (adjustment, (int)new_value); break; } @@ -531,50 +541,6 @@ view_update_range_and_current_page (EvView *view) view->scale); } -static void -view_scroll_to_page (EvView *view, gint new_page) -{ - EvPageCache *page_cache = view->page_cache; - int old_width, old_height; - int new_width, new_height; - int max_height, n_rows; - - ev_page_cache_get_size (page_cache, - view->current_page, - view->scale, - &old_width, &old_height); - - ev_page_cache_get_size (page_cache, - new_page, - view->scale, - &new_width, &new_height); - - compute_border (view, new_width, new_height, &(view->border)); - - if (new_width != old_width || new_height != old_height) - gtk_widget_queue_resize (GTK_WIDGET (view)); - else - gtk_widget_queue_draw (GTK_WIDGET (view)); - - if (view->continuous) { - - n_rows = view->dual_page ? new_page / 2 : new_page; - - get_bounding_box_size (view, NULL, &max_height); - - gtk_adjustment_clamp_page(view->vadjustment, - (max_height + view->spacing) * n_rows, - (max_height + view->spacing) * n_rows + - view->vadjustment->page_size); - } else { - gtk_adjustment_set_value (view->vadjustment, - view->vadjustment->lower); - } - - view->current_page = new_page; - view_update_range_and_current_page (view); -} - static void set_scroll_adjustment (EvView *view, GtkOrientation orientation, @@ -614,7 +580,7 @@ ev_view_set_scroll_adjustments (EvView *view, set_scroll_adjustment (view, GTK_ORIENTATION_HORIZONTAL, hadjustment); set_scroll_adjustment (view, GTK_ORIENTATION_VERTICAL, vadjustment); - view_update_adjustments (view); + on_adjustment_value_changed (NULL, view); } static void @@ -871,8 +837,8 @@ get_page_extents (EvView *view, y = view->spacing; /* Adjust for extra allocation */ - x = x + MAX (0, widget->allocation.width - (width + view->spacing * 2))/2; - y = y + MAX (0, widget->allocation.height - (height + view->spacing * 2))/2; + x = x + MAX (0, widget->allocation.width - (width + border->left + border->right + view->spacing * 2))/2; + y = y + MAX (0, widget->allocation.height - (height + border->top + border->bottom + view->spacing * 2))/2; } page_area->x = x; @@ -1172,9 +1138,6 @@ ev_view_size_request (GtkWidget *widget, { EvView *view = EV_VIEW (widget); - if (!GTK_WIDGET_REALIZED (widget)) - return; - if (view->document == NULL) { requisition->width = 1; requisition->height = 1; @@ -1215,6 +1178,7 @@ ev_view_size_allocate (GtkWidget *widget, view_set_adjustment_values (view, GTK_ORIENTATION_VERTICAL); view->pending_scroll = SCROLL_TO_KEEP_POSITION; + view->pending_resize = FALSE; if (view->document) view_update_range_and_current_page (view); @@ -1260,15 +1224,6 @@ ev_view_realize (GtkWidget *widget) gdk_window_set_background (widget->window, &widget->style->black); else gdk_window_set_background (widget->window, &widget->style->mid [GTK_STATE_NORMAL]); - - if (view->document) { - /* We can't get page size without a target, so we have to - * queue a size request at realization. Could be fixed - * with EvDocument changes to allow setting a GdkScreen - * without setting a target. - */ - gtk_widget_queue_resize (widget); - } } static void @@ -1286,14 +1241,16 @@ ev_view_scroll_event (GtkWidget *widget, GdkEventScroll *event) ev_view_set_sizing_mode (view, EV_SIZING_FREE); - if ((event->direction == GDK_SCROLL_UP || - event->direction == GDK_SCROLL_LEFT) && - ev_view_can_zoom_in (view)) { - ev_view_zoom_in (view); - } else if (ev_view_can_zoom_out (view)) { - ev_view_zoom_out (view); - } - + if (event->direction == GDK_SCROLL_UP || + event->direction == GDK_SCROLL_LEFT) { + if (ev_view_can_zoom_in (view)) { + ev_view_zoom_in (view); + } + } else { + if (ev_view_can_zoom_out (view)) { + ev_view_zoom_out (view); + } + } return TRUE; } @@ -1587,14 +1544,12 @@ draw_one_page (EvView *view, GdkRectangle real_page_area; g_assert (view->document); - - if (!gdk_rectangle_intersect (page_area, expose_area, &overlap)) + if (! gdk_rectangle_intersect (page_area, expose_area, &overlap)) return; ev_page_cache_get_size (view->page_cache, page, view->scale, &width, &height); - /* Render the document itself */ real_page_area = *page_area; @@ -1603,36 +1558,37 @@ draw_one_page (EvView *view, real_page_area.width -= (border->left + border->right); real_page_area.height -= (border->top + border->bottom); - if (! gdk_rectangle_intersect (&real_page_area, expose_area, &overlap)) - return; - ev_document_misc_paint_one_page (GTK_WIDGET(view)->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) && - height == gdk_pixbuf_get_height (current_pixbuf)) - scaled_image = g_object_ref (current_pixbuf); - else - scaled_image = gdk_pixbuf_scale_simple (current_pixbuf, - width, height, - GDK_INTERP_NEAREST); + if (gdk_rectangle_intersect (&real_page_area, expose_area, &overlap)) { + current_pixbuf = ev_pixbuf_cache_get_pixbuf (view->pixbuf_cache, page); - if (scaled_image) { - gdk_draw_pixbuf (GTK_WIDGET(view)->window, - GTK_WIDGET (view)->style->fg_gc[GTK_STATE_NORMAL], - scaled_image, - overlap.x - real_page_area.x, - overlap.y - real_page_area.y, - overlap.x, overlap.y, - overlap.width, overlap.height, - GDK_RGB_DITHER_NORMAL, - 0, 0); - g_object_unref (scaled_image); + if (current_pixbuf == NULL) + scaled_image = NULL; + else if (width == gdk_pixbuf_get_width (current_pixbuf) && + height == gdk_pixbuf_get_height (current_pixbuf)) + scaled_image = g_object_ref (current_pixbuf); + else + /* FIXME: We don't want to scale the whole area, just the right + * area of it */ + scaled_image = gdk_pixbuf_scale_simple (current_pixbuf, + width, height, + GDK_INTERP_NEAREST); + + if (scaled_image) { + gdk_draw_pixbuf (GTK_WIDGET(view)->window, + GTK_WIDGET (view)->style->fg_gc[GTK_STATE_NORMAL], + scaled_image, + overlap.x - real_page_area.x, + overlap.y - real_page_area.y, + overlap.x, overlap.y, + overlap.width, overlap.height, + GDK_RGB_DITHER_NORMAL, + 0, 0); + g_object_unref (scaled_image); + } } } @@ -1696,6 +1652,9 @@ ev_view_set_property (GObject *object, case PROP_SIZING_MODE: ev_view_set_sizing_mode (view, g_value_get_enum (value)); break; + case PROP_ZOOM: + ev_view_set_zoom (view, g_value_get_double (value), FALSE); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -1732,6 +1691,9 @@ ev_view_get_property (GObject *object, case PROP_SIZING_MODE: g_value_set_enum (value, view->sizing_mode); break; + case PROP_ZOOM: + g_value_set_double (value, view->scale); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -1847,6 +1809,16 @@ ev_view_class_init (EvViewClass *class) EV_SIZING_FIT_WIDTH, G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_ZOOM, + g_param_spec_double ("zoom", + "Zoom factor", + "Zoom factor", + MIN_SCALE, + MAX_SCALE, + 1.0, + G_PARAM_READWRITE)); + binding_set = gtk_binding_set_by_class (class); add_scroll_binding_keypad (binding_set, GDK_Left, GTK_SCROLL_STEP_BACKWARD, TRUE); @@ -1860,7 +1832,7 @@ ev_view_init (EvView *view) { GTK_WIDGET_SET_FLAGS (view, GTK_CAN_FOCUS); - view->spacing = 10; + view->spacing = 5; view->scale = 1.0; view->current_page = 0; view->pressed_button = -1; @@ -1901,8 +1873,10 @@ page_changed_cb (EvPageCache *page_cache, EvView *view) { if (view->current_page != new_page) { - - view_scroll_to_page (view, new_page); + + view->current_page = new_page; + view->pending_scroll = SCROLL_TO_CURRENT_PAGE; + gtk_widget_queue_resize (GTK_WIDGET (view)); if (EV_IS_DOCUMENT_FIND (view->document)) { view->find_page = new_page; @@ -1915,8 +1889,34 @@ page_changed_cb (EvPageCache *page_cache, static void on_adjustment_value_changed (GtkAdjustment *adjustment, EvView *view) { - view_update_adjustments (view); -} + int dx = 0, dy = 0; + + if (! GTK_WIDGET_REALIZED (view)) + return; + + if (view->hadjustment) { + dx = view->scroll_x - (int) view->hadjustment->value; + view->scroll_x = (int) view->hadjustment->value; + } else { + view->scroll_x = 0; + } + + if (view->vadjustment) { + dy = view->scroll_y - (int) view->vadjustment->value; + view->scroll_y = (int) view->vadjustment->value; + } else { + view->scroll_y = 0; + } + + + if (view->pending_resize) + gtk_widget_queue_draw (GTK_WIDGET (view)); + else + gdk_window_scroll (GTK_WIDGET (view)->window, dx, dy); + + + if (view->document) + view_update_range_and_current_page (view);} GtkWidget* ev_view_new (void) @@ -1957,7 +1957,6 @@ ev_view_set_document (EvView *view, view); } view->page_cache = ev_document_get_page_cache (view->document); - view->pending_scroll = SCROLL_TO_CURRENT_PAGE; g_signal_connect (view->page_cache, "page-changed", G_CALLBACK (page_changed_cb), view); view->pixbuf_cache = ev_pixbuf_cache_new (view->document); g_signal_connect (view->pixbuf_cache, "job-finished", G_CALLBACK (job_finished_cb), view); @@ -1986,9 +1985,13 @@ ev_view_set_zoom (EvView *view, if (ABS (view->scale - scale) < EPSILON) return; - view->scale = scale; + view->scale = scale; + view->pending_resize = TRUE; + gtk_widget_queue_resize (GTK_WIDGET (view)); + + g_object_notify (G_OBJECT (view), "zoom"); } double @@ -2423,10 +2426,8 @@ update_find_status_message (EvView *view) } else { double percent; - ev_document_doc_mutex_lock (); percent = ev_document_find_get_progress (EV_DOCUMENT_FIND (view->document)); - ev_document_doc_mutex_unlock (); if (percent >= (1.0 - 1e-10)) { message = g_strdup (_("Not found")); } else { @@ -2467,15 +2468,11 @@ jump_to_find_result (EvView *view) int n_results; int page = view->find_page; - ev_document_doc_mutex_lock (); n_results = ev_document_find_get_n_results (find, page); - ev_document_doc_mutex_unlock (); if (n_results > view->find_result) { - ev_document_doc_mutex_lock (); ev_document_find_get_result (find, page, view->find_result, &rect); - ev_document_doc_mutex_unlock (); doc_rect_to_view_rect (view, page, &rect, &view_rect); ensure_rectangle_is_visible (view, &view_rect); @@ -2519,9 +2516,7 @@ ev_view_can_find_next (EvView *view) if (EV_IS_DOCUMENT_FIND (view->document)) { EvDocumentFind *find = EV_DOCUMENT_FIND (view->document); - ev_document_doc_mutex_lock (); n_results = ev_document_find_get_n_results (find, view->current_page); - ev_document_doc_mutex_unlock (); } return n_results > 0; @@ -2535,9 +2530,7 @@ ev_view_find_next (EvView *view) EvDocumentFind *find = EV_DOCUMENT_FIND (view->document); page_cache = ev_document_get_page_cache (view->document); - ev_document_doc_mutex_lock (); n_results = ev_document_find_get_n_results (find, view->current_page); - ev_document_doc_mutex_unlock (); n_pages = ev_page_cache_get_n_pages (page_cache); @@ -2567,9 +2560,7 @@ ev_view_find_previous (EvView *view) page_cache = ev_document_get_page_cache (view->document); - ev_document_doc_mutex_lock (); n_results = ev_document_find_get_n_results (find, view->current_page); - ev_document_doc_mutex_unlock (); n_pages = ev_page_cache_get_n_pages (page_cache);