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=129d87c334928e2599ec1c020d5457f3704cad82;hb=a003d7ffe3fd328ae430ae613a8da037f766aabb;hp=5944e348305db28d0e60026f86090b3a48e4969f;hpb=1af6600934d1f723e5b492b8322e52a1144fb0af;p=evince.git diff --git a/shell/ev-view.c b/shell/ev-view.c index 5944e348..129d87c3 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -42,6 +42,7 @@ #include "ev-job-queue.h" #include "ev-page-cache.h" #include "ev-pixbuf-cache.h" +#include "ev-transition-animation.h" #if !GTK_CHECK_VERSION (2, 11, 7) #include "ev-tooltip.h" #endif @@ -1574,7 +1575,8 @@ ev_view_handle_cursor_over_xy (EvView *view, gint x, gint y) } else { if (view->cursor == EV_VIEW_CURSOR_LINK || view->cursor == EV_VIEW_CURSOR_IBEAM || - view->cursor == EV_VIEW_CURSOR_DRAG) + view->cursor == EV_VIEW_CURSOR_DRAG || + view->cursor == EV_VIEW_CURSOR_AUTOSCROLL) ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL); } } @@ -1905,7 +1907,8 @@ ev_view_form_field_choice_changed (GtkWidget *widget, gint item; item = gtk_combo_box_get_active (GTK_COMBO_BOX (widget)); - if (GPOINTER_TO_INT (field_choice->selected_items->data) != item) { + if (!field_choice->selected_items || + GPOINTER_TO_INT (field_choice->selected_items->data) != item) { g_list_free (field_choice->selected_items); field_choice->selected_items = NULL; field_choice->selected_items = g_list_prepend (field_choice->selected_items, @@ -2384,15 +2387,16 @@ ev_view_scroll_event (GtkWidget *widget, GdkEventScroll *event) } view->jump_to_find_result = FALSE; + /* Shift+Wheel scrolls the in the perpendicular direction */ if (state & GDK_SHIFT_MASK) { if (event->direction == GDK_SCROLL_UP) event->direction = GDK_SCROLL_LEFT; - if (event->direction == GDK_SCROLL_LEFT) + else if (event->direction == GDK_SCROLL_LEFT) event->direction = GDK_SCROLL_UP; - if (event->direction == GDK_SCROLL_DOWN) + else if (event->direction == GDK_SCROLL_DOWN) event->direction = GDK_SCROLL_RIGHT; - if (event->direction == GDK_SCROLL_RIGHT) + else if (event->direction == GDK_SCROLL_RIGHT) event->direction = GDK_SCROLL_DOWN; event->state &= ~GDK_SHIFT_MASK; @@ -2479,6 +2483,24 @@ ev_view_expose_event (GtkWidget *widget, cairo_t *cr; gint i; + if (view->animation && ev_transition_animation_ready (view->animation)) { + GdkRectangle page_area; + GtkBorder border; + + if (get_page_extents (view, view->current_page, &page_area, &border)) { + cr = gdk_cairo_create (view->layout.bin_window); + + /* normalize to x=0, y=0 */ + cairo_translate (cr, page_area.x, page_area.y); + page_area.x = page_area.y = 0; + + ev_transition_animation_paint (view->animation, cr, page_area); + cairo_destroy (cr); + } + + return TRUE; + } + if (view->presentation) { switch (view->presentation_state) { case EV_PRESENTATION_END: { @@ -2667,15 +2689,12 @@ ev_view_button_press_event (GtkWidget *widget, view->pressed_button = event->button; view->selection_info.in_drag = FALSE; + + if (view->scroll_info.autoscrolling) + return TRUE; switch (event->button) { case 1: { - - if (view->scroll_info.autoscrolling == TRUE) { - view->scroll_info.autoscrolling = FALSE; - return TRUE; - } - EvImage *image; EvFormField *field; @@ -2714,10 +2733,6 @@ 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); @@ -2727,8 +2742,7 @@ ev_view_button_press_event (GtkWidget *widget, return TRUE; case 3: - if (!view->scroll_info.autoscrolling) - view->scroll_info.start_y = event->y; + view->scroll_info.start_y = event->y; return ev_view_do_popup_menu (view, event->x, event->y); } @@ -2775,16 +2789,28 @@ ev_view_drag_data_get (GtkWidget *widget, if (view->image_dnd_info.image) { GdkPixbuf *pixbuf; - pixbuf = ev_image_get_pixbuf (view->image_dnd_info.image); + ev_document_doc_mutex_lock (); + pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (view->document), + view->image_dnd_info.image); + ev_document_doc_mutex_unlock (); + gtk_selection_data_set_pixbuf (selection_data, pixbuf); + g_object_unref (pixbuf); } break; case TARGET_DND_URI: if (view->image_dnd_info.image) { + GdkPixbuf *pixbuf; const gchar *tmp_uri; gchar **uris; - tmp_uri = ev_image_save_tmp (view->image_dnd_info.image); + ev_document_doc_mutex_lock (); + pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (view->document), + view->image_dnd_info.image); + ev_document_doc_mutex_unlock (); + + tmp_uri = ev_image_save_tmp (view->image_dnd_info.image, pixbuf); + g_object_unref (pixbuf); uris = g_new0 (gchar *, 2); uris[0] = (gchar *)tmp_uri; @@ -2973,6 +2999,7 @@ ev_view_motion_notify_event (GtkWidget *widget, if (view->scroll_info.autoscrolling) { view->scroll_info.last_y = y; + return TRUE; } if (view->selection_info.in_drag) { @@ -3106,19 +3133,30 @@ ev_view_button_release_event (GtkWidget *widget, EvView *view = EV_VIEW (widget); EvLink *link = NULL; - view->drag_info.in_drag = FALSE; view->image_dnd_info.in_drag = FALSE; - - view->drag_info.release_timeout_id = g_timeout_add (20, - (GSourceFunc)ev_view_scroll_drag_release, view); - if (view->pressed_button == 2) { - ev_view_handle_cursor_over_xy (view, event->x, event->y); + if (view->scroll_info.autoscrolling) { + ev_view_autoscroll_stop (view); + view->pressed_button = -1; + + return TRUE; + } + + if (view->drag_info.in_drag) { + view->drag_info.release_timeout_id = + g_timeout_add (20, + (GSourceFunc)ev_view_scroll_drag_release, view); } - if (view->document && view->pressed_button != 3) { + if (view->document && !view->drag_info.in_drag && view->pressed_button != 3) { link = ev_view_get_link_at_location (view, event->x, event->y); } + + view->drag_info.in_drag = FALSE; + + if (view->pressed_button == 2) { + ev_view_handle_cursor_over_xy (view, event->x, event->y); + } view->pressed_button = -1; @@ -3601,12 +3639,6 @@ draw_loading_text (EvView *view, cairo_t *cr; gint width, height; - /* Don't annoy users with loading messages during presentations. - * FIXME: Temporary "workaround" for - * http://bugzilla.gnome.org/show_bug.cgi?id=320352 */ - if (view->presentation) - return; - if (!view->loading_text) { const gchar *loading_text = _("Loading..."); PangoLayout *layout; @@ -3707,9 +3739,12 @@ draw_one_page (EvView *view, page_surface = ev_pixbuf_cache_get_surface (view->pixbuf_cache, page); if (!page_surface) { - draw_loading_text (view, - &real_page_area, - expose_area); + if (!view->presentation) { + draw_loading_text (view, + &real_page_area, + expose_area); + } + *page_ready = FALSE; return; @@ -3725,7 +3760,7 @@ draw_one_page (EvView *view, cairo_save (cr); cairo_translate (cr, overlap.x, overlap.y); - + if (width != page_width || height != page_height) { cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_FAST); @@ -4204,11 +4239,76 @@ find_changed_cb (EvDocument *document, int page, EvView *view) gtk_widget_queue_draw (GTK_WIDGET (view)); } +static void +ev_view_change_page (EvView *view, + gint new_page) +{ + gint x, y; + + view->current_page = new_page; + view->pending_scroll = SCROLL_TO_PAGE_POSITION; + + if (view->presentation) + ev_view_presentation_transition_start (view); + + gtk_widget_get_pointer (GTK_WIDGET (view), &x, &y); + ev_view_handle_cursor_over_xy (view, x, y); + + gtk_widget_queue_resize (GTK_WIDGET (view)); +} + +static void +ev_view_transition_animation_finish (EvTransitionAnimation *animation, + EvView *view) +{ + g_object_unref (view->animation); + view->animation = NULL; + ev_view_change_page (view, view->current_page); +} + +static void +ev_view_transition_animation_frame (EvTransitionAnimation *animation, + gdouble progress, + EvView *view) +{ + gtk_widget_queue_draw (GTK_WIDGET (view)); +} + +static void +ev_view_presentation_animation_start (EvView *view, + int new_page) +{ + EvTransitionEffect *effect = NULL; + cairo_surface_t *surface; + + if (EV_IS_DOCUMENT_TRANSITION (view->document)) + effect = ev_document_transition_get_effect (EV_DOCUMENT_TRANSITION (view->document), + view->current_page); + if (!effect) + return; + + surface = ev_pixbuf_cache_get_surface (view->pixbuf_cache, view->current_page); + view->animation = ev_transition_animation_new (effect); + ev_transition_animation_set_origin_surface (view->animation, surface); + + g_signal_connect (view->animation, "frame", + G_CALLBACK (ev_view_transition_animation_frame), view); + g_signal_connect (view->animation, "finished", + G_CALLBACK (ev_view_transition_animation_finish), view); +} + static void job_finished_cb (EvPixbufCache *pixbuf_cache, GdkRegion *region, EvView *view) { + if (view->animation) { + cairo_surface_t *surface; + + surface = ev_pixbuf_cache_get_surface (pixbuf_cache, view->current_page); + ev_transition_animation_set_dest_surface (view->animation, surface); + } + if (region) { gdk_window_invalidate_region (view->layout.bin_window, region, TRUE); @@ -4223,18 +4323,10 @@ page_changed_cb (EvPageCache *page_cache, EvView *view) { if (view->current_page != new_page) { - gint x, y; - - view->current_page = new_page; - view->pending_scroll = SCROLL_TO_PAGE_POSITION; - if (view->presentation) - ev_view_presentation_transition_start (view); - - gtk_widget_get_pointer (GTK_WIDGET (view), &x, &y); - ev_view_handle_cursor_over_xy (view, x, y); - - gtk_widget_queue_resize (GTK_WIDGET (view)); + ev_view_presentation_animation_start (view, new_page); + + ev_view_change_page (view, new_page); } else { gtk_widget_queue_draw (GTK_WIDGET (view)); } @@ -4339,7 +4431,8 @@ ev_view_set_loading (EvView *view, gtk_widget_queue_draw (GTK_WIDGET (view)); } -static gboolean ev_view_autoscroll_cb (EvView *view) +static gboolean +ev_view_autoscroll_cb (EvView *view) { gdouble speed, value; @@ -4372,10 +4465,43 @@ static gboolean ev_view_autoscroll_cb (EvView *view) } -void ev_view_autoscroll(EvView *view) +void +ev_view_autoscroll_start (EvView *view) { + gint x, y; + + g_return_if_fail (EV_IS_VIEW (view)); + + if (view->scroll_info.autoscrolling) + return; + view->scroll_info.autoscrolling = TRUE; - view->scroll_info.timeout_id = g_timeout_add (20, (GSourceFunc)(ev_view_autoscroll_cb), view); + view->scroll_info.timeout_id = + g_timeout_add (20, (GSourceFunc)ev_view_autoscroll_cb, + view); + + gtk_widget_get_pointer (GTK_WIDGET (view), &x, &y); + ev_view_handle_cursor_over_xy (view, x, y); +} + +void +ev_view_autoscroll_stop (EvView *view) +{ + gint x, y; + + g_return_if_fail (EV_IS_VIEW (view)); + + if (!view->scroll_info.autoscrolling) + return; + + view->scroll_info.autoscrolling = FALSE; + if (view->scroll_info.timeout_id) { + g_source_remove (view->scroll_info.timeout_id); + view->scroll_info.timeout_id = 0; + } + + gtk_widget_get_pointer (GTK_WIDGET (view), &x, &y); + ev_view_handle_cursor_over_xy (view, x, y); } void @@ -4579,9 +4705,15 @@ ev_view_set_presentation (EvView *view, if (presentation) ev_view_presentation_transition_start (view); - else + else { ev_view_presentation_transition_stop (view); + if (view->animation) { + /* stop any running animation */ + ev_view_transition_animation_finish (view->animation, view); + } + } + if (GTK_WIDGET_REALIZED (view)) { if (view->presentation) gdk_window_set_background (view->layout.bin_window, @@ -4631,17 +4763,10 @@ ev_view_presentation_transition_start (EvView *view) duration = ev_document_transition_get_page_duration (EV_DOCUMENT_TRANSITION (view->document), view->current_page); if (duration > 0) { -#if GLIB_CHECK_VERSION (2, 13, 0) view->trans_timeout_id = g_timeout_add_seconds (duration, (GSourceFunc) transition_next_page, view); -#else - view->trans_timeout_id = - g_timeout_add (duration * 1000, - (GSourceFunc) transition_next_page, - view); -#endif } } @@ -5771,7 +5896,12 @@ ev_view_next_page (EvView *view) view->presentation_state == EV_PRESENTATION_WHITE)) { ev_view_reset_presentation_state (view); return FALSE; - } + } + + if (view->animation) { + ev_view_transition_animation_finish (view->animation, view); + return TRUE; + } ev_view_presentation_transition_stop (view); ev_view_reset_presentation_state (view); @@ -5822,6 +5952,11 @@ ev_view_previous_page (EvView *view) return FALSE; } + if (view->animation) { + ev_view_transition_animation_finish (view->animation, view); + return TRUE; + } + ev_view_reset_presentation_state (view); page = ev_page_cache_get_current_page (view->page_cache);