X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=sidebyside;f=libview%2Fev-view-presentation.c;h=05f879923748b74165505647a21f2ec0f747f304;hb=83ee6052d7eeb4cfa100f4533d6259573d65efe9;hp=72af799cf3d857ff36441fb76e9964690d0c7dd4;hpb=e288b2cb68ac2645bfee992566bd8f1974388fb1;p=evince.git diff --git a/libview/ev-view-presentation.c b/libview/ev-view-presentation.c index 72af799c..05f87992 100644 --- a/libview/ev-view-presentation.c +++ b/libview/ev-view-presentation.c @@ -41,6 +41,7 @@ enum { enum { CHANGE_PAGE, + FINISHED, N_SIGNALS }; @@ -56,6 +57,7 @@ struct _EvViewPresentation GtkWidget base; guint current_page; + cairo_surface_t *current_surface; EvDocument *document; guint rotation; EvPresentationState state; @@ -91,6 +93,7 @@ struct _EvViewPresentationClass /* signals */ void (* change_page) (EvViewPresentation *pview, GtkScrollType scroll); + void (* finished) (EvViewPresentation *pview); }; static guint signals[N_SIGNALS] = { 0 }; @@ -234,7 +237,7 @@ ev_view_presentation_transition_start (EvViewPresentation *pview) duration = ev_document_transition_get_page_duration (EV_DOCUMENT_TRANSITION (pview->document), pview->current_page); - if (duration > 0) { + if (duration >= 0) { pview->trans_timeout_id = g_timeout_add_seconds (duration, (GSourceFunc) transition_next_page, @@ -289,7 +292,9 @@ ev_view_presentation_animation_start (EvViewPresentation *pview, pview->animation = ev_transition_animation_new (effect); surface = EV_JOB_RENDER (pview->curr_job)->surface; - ev_transition_animation_set_origin_surface (pview->animation, surface); + ev_transition_animation_set_origin_surface (pview->animation, + surface != NULL ? + surface : pview->current_surface); jump = new_page - pview->current_page; if (jump == -1) @@ -875,6 +880,19 @@ ev_view_presentation_hide_cursor_timeout_start (EvViewPresentation *pview) pview); } +static void +ev_view_presentation_update_current_surface (EvViewPresentation *pview, + cairo_surface_t *surface) +{ + if (!surface || pview->current_surface == surface) + return; + + cairo_surface_reference (surface); + if (pview->current_surface) + cairo_surface_destroy (pview->current_surface); + pview->current_surface = surface; +} + static void ev_view_presentation_destroy (GtkObject *object) { @@ -904,6 +922,11 @@ ev_view_presentation_destroy (GtkObject *object) pview->next_job = NULL; } + if (pview->current_surface) { + cairo_surface_destroy (pview->current_surface); + pview->current_surface = NULL; + } + if (pview->page_cache) { g_object_unref (pview->page_cache); pview->page_cache = NULL; @@ -953,7 +976,7 @@ ev_view_presentation_draw_end_page (EvViewPresentation *pview) PangoFontDescription *font_desc; gchar *markup; GdkRectangle area = {0}; - const gchar *text = _("End of presentation. Press Escape to exit."); + const gchar *text = _("End of presentation. Click to exit."); if (pview->state != EV_PRESENTATION_END) return; @@ -1016,6 +1039,9 @@ ev_view_presentation_expose_event (GtkWidget *widget, cairo_translate (cr, page_area.x, page_area.y); page_area.x = page_area.y = 0; + /* Try to fix rounding errors */ + page_area.width--; + ev_transition_animation_paint (pview->animation, cr, page_area); cairo_destroy (cr); } @@ -1024,19 +1050,25 @@ ev_view_presentation_expose_event (GtkWidget *widget, } surface = pview->curr_job ? EV_JOB_RENDER (pview->curr_job)->surface : NULL; - if (!surface) + if (surface) { + ev_view_presentation_update_current_surface (pview, surface); + } else if (pview->current_surface) { + surface = pview->current_surface; + } else { return FALSE; + } ev_view_presentation_get_page_area (pview, &page_area); if (gdk_rectangle_intersect (&page_area, &(event->area), &overlap)) { cr = gdk_cairo_create (widget->window); - cairo_translate (cr, overlap.x, overlap.y); - cairo_surface_set_device_offset (surface, - overlap.x - page_area.x, - overlap.y - page_area.y); - cairo_set_source_surface (cr, surface, 0, 0); - cairo_paint (cr); + /* Try to fix rounding errors. See bug #438760 */ + if (overlap.width == page_area.width) + overlap.width--; + + cairo_rectangle (cr, overlap.x, overlap.y, overlap.width, overlap.height); + cairo_set_source_surface (cr, surface, page_area.x, page_area.y); + cairo_fill (cr); cairo_destroy (cr); } @@ -1071,6 +1103,22 @@ ev_view_presentation_key_press_event (GtkWidget *widget, ev_view_presentation_set_white (pview); return TRUE; + case GDK_Home: + if (pview->state == EV_PRESENTATION_NORMAL) { + ev_view_presentation_update_current_page (pview, 0); + return TRUE; + } + break; + case GDK_End: + if (pview->state == EV_PRESENTATION_NORMAL) { + gint page; + + page = ev_document_get_n_pages (pview->document) - 1; + ev_view_presentation_update_current_page (pview, page); + + return TRUE; + } + break; default: break; } @@ -1103,6 +1151,12 @@ ev_view_presentation_button_release_event (GtkWidget *widget, case 1: { EvLink *link; + if (pview->state == EV_PRESENTATION_END) { + g_signal_emit (pview, signals[FINISHED], 0, NULL); + + return FALSE; + } + link = ev_view_presentation_get_link_at_location (pview, event->x, event->y); @@ -1353,6 +1407,15 @@ ev_view_presentation_class_init (EvViewPresentationClass *klass) g_cclosure_marshal_VOID__ENUM, G_TYPE_NONE, 1, GTK_TYPE_SCROLL_TYPE); + signals[FINISHED] = + g_signal_new ("finished", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EvViewPresentationClass, finished), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0, + G_TYPE_NONE); binding_set = gtk_binding_set_by_class (klass); add_change_page_binding_keypad (binding_set, GDK_Left, 0, GTK_SCROLL_PAGE_BACKWARD);