[evince] libview: Let handle_cursor_over_xy handle link preview



commit c73b2f5ae01908d813bc04f15bfe51c3f7708004
Author: Mads Chr. Olesen <mads mchro dk>
Date:   Sat Jun 27 12:15:30 2020 +0200

    libview: Let handle_cursor_over_xy handle link preview
    
    Move link preview popover from ev_view_query_tooltip to
    ev_view_handle_cursor_over_xy
    
    Partially fixes #662

 libview/ev-view.c | 240 ++++++++++++++++++++++++++++--------------------------
 1 file changed, 125 insertions(+), 115 deletions(-)
---
diff --git a/libview/ev-view.c b/libview/ev-view.c
index bb483119..aa3491ce 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -149,7 +149,16 @@ static EvLink *   ev_view_get_link_at_location                  (EvView             
*view,
                                                              gdouble             y);
 static char*      tip_from_link                              (EvView             *view,
                                                              EvLink             *link);
-static void       _ev_view_cleanup_link_preview_popover      (EvView             *view);
+static void       ev_view_link_preview_popover_cleanup       (EvView             *view);
+static void       get_link_area                              (EvView             *view,
+                                                             gint                x,
+                                                             gint                y,
+                                                             EvLink             *link,
+                                                             GdkRectangle       *area);
+static void       link_preview_show_thumbnail                (GdkPixbuf          *pixbuf,
+                                                             EvView             *view);
+static void       link_preview_job_finished_cb               (EvJobThumbnail     *job,
+                                                             EvView             *view);
 /*** Forms ***/
 static EvFormField *ev_view_get_form_field_at_location       (EvView             *view,
                                                               gdouble            x,
@@ -2196,35 +2205,120 @@ ev_view_handle_cursor_over_xy (EvView *view, gint x, gint y)
        }
 
        link = ev_view_get_link_at_location (view, x, y);
-        if (link) {
+       if (link) {
+               GdkRectangle     link_area;
+               EvLinkAction    *action;
+               EvLinkDest      *dest;
+               EvLinkDestType   type;
+               GtkWidget       *popover, *spinner;
+               cairo_surface_t *page_surface = NULL;
+               guint            link_dest_page;
+               EvPoint          link_dest_doc;
+               GdkPoint         link_dest_view;
+
                ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
-       } else if ((field = ev_view_get_form_field_at_location (view, x, y))) {
-               if (field->is_read_only) {
-                       if (view->cursor == EV_VIEW_CURSOR_LINK ||
-                           view->cursor == EV_VIEW_CURSOR_IBEAM ||
-                           view->cursor == EV_VIEW_CURSOR_DRAG)
+
+               if (link == view->link_preview.link)
+                       return;
+
+               /* Display thumbnail, if applicable */
+               action = ev_link_get_action (link);
+               if (!action)
+                       return;
+
+               dest = ev_link_action_get_dest (action);
+               if (!dest)
+                       return;
+
+               type = ev_link_dest_get_dest_type (dest);
+               if (type == EV_LINK_DEST_TYPE_NAMED) {
+                       dest = ev_document_links_find_link_dest (EV_DOCUMENT_LINKS (view->document),
+                                                                ev_link_dest_get_named_dest (dest));
+               }
+
+               ev_view_link_preview_popover_cleanup (view);
+
+               /* Init popover */
+               view->link_preview.popover = popover = gtk_popover_new (GTK_WIDGET (view));
+               get_link_area (view, x, y, link, &link_area);
+               gtk_popover_set_pointing_to (GTK_POPOVER (popover), &link_area);
+               gtk_popover_set_modal (GTK_POPOVER (popover), FALSE);
+
+               spinner = gtk_spinner_new ();
+               gtk_spinner_start (GTK_SPINNER (spinner));
+               gtk_container_add (GTK_CONTAINER (popover) , spinner);
+               gtk_widget_show (spinner);
+
+               /* Start thumbnailing job async */
+               link_dest_page = ev_link_dest_get_page (dest);
+               view->link_preview.job = ev_job_thumbnail_new (view->document,
+                                                              link_dest_page,
+                                                              view->rotation,
+                                                              view->scale);
+               ev_job_thumbnail_set_output_format (EV_JOB_THUMBNAIL (view->link_preview.job),
+                                                   EV_JOB_THUMBNAIL_SURFACE);
+
+               link_dest_doc.x = ev_link_dest_get_left (dest, NULL);
+               link_dest_doc.y = ev_link_dest_get_top (dest, NULL);
+               _ev_view_transform_doc_point_by_rotation_scale (view, link_dest_page,
+                                                               &link_dest_doc, &link_dest_view);
+               view->link_preview.left = link_dest_view.x;
+               view->link_preview.top = link_dest_view.y;
+               view->link_preview.link = link;
+
+               page_surface = ev_pixbuf_cache_get_surface (view->pixbuf_cache, link_dest_page);
+
+               if (page_surface) {
+                       GdkPixbuf *slice;
+
+                       slice = gdk_pixbuf_get_from_surface (page_surface, 0, 0,
+                                                            cairo_image_surface_get_width(page_surface),
+                                                            cairo_image_surface_get_height(page_surface));
+                       link_preview_show_thumbnail (slice, view);
+                       g_object_unref(slice);
+               } else {
+                       g_signal_connect (view->link_preview.job, "finished",
+                                         G_CALLBACK (link_preview_job_finished_cb),
+                                         view);
+                       ev_job_scheduler_push_job (view->link_preview.job, EV_JOB_PRIORITY_LOW);
+               }
+
+               if (type == EV_LINK_DEST_TYPE_NAMED)
+                       g_object_unref (dest);
+
+               gtk_widget_show (popover);
+       } else {
+               ev_view_link_preview_popover_cleanup (view);
+               view->link_preview.link = NULL;
+
+               if ((field = ev_view_get_form_field_at_location (view, x, y))) {
+                       if (field->is_read_only) {
+                               if (view->cursor == EV_VIEW_CURSOR_LINK ||
+                                   view->cursor == EV_VIEW_CURSOR_IBEAM ||
+                                   view->cursor == EV_VIEW_CURSOR_DRAG)
+                                       ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL);
+                       } else if (EV_IS_FORM_FIELD_TEXT (field)) {
+                               ev_view_set_cursor (view, EV_VIEW_CURSOR_IBEAM);
+                       } else {
+                               ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
+                       }
+               } else if ((media = ev_view_get_media_at_location (view, x, y))) {
+                       if (!ev_view_find_player_for_media (view, media))
+                               ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
+                       else
                                ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL);
-               } else if (EV_IS_FORM_FIELD_TEXT (field)) {
+               } else if ((annot = ev_view_get_annotation_at_location (view, x, y))) {
+                       ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
+               } else if (location_in_text (view, x + view->scroll_x, y + view->scroll_y)) {
                        ev_view_set_cursor (view, EV_VIEW_CURSOR_IBEAM);
                } else {
-                       ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
+                       if (view->cursor == EV_VIEW_CURSOR_LINK ||
+                           view->cursor == EV_VIEW_CURSOR_IBEAM ||
+                           view->cursor == EV_VIEW_CURSOR_DRAG ||
+                           view->cursor == EV_VIEW_CURSOR_AUTOSCROLL ||
+                           view->cursor == EV_VIEW_CURSOR_ADD)
+                               ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL);
                }
-       } else if ((media = ev_view_get_media_at_location (view, x, y))) {
-               if (!ev_view_find_player_for_media (view, media))
-                       ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
-               else
-                       ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL);
-       } else if ((annot = ev_view_get_annotation_at_location (view, x, y))) {
-               ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
-       } else if (location_in_text (view, x + view->scroll_x, y + view->scroll_y)) {
-               ev_view_set_cursor (view, EV_VIEW_CURSOR_IBEAM);
-       } 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_AUTOSCROLL ||
-                   view->cursor == EV_VIEW_CURSOR_ADD)
-                       ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL);
        }
 
        if (link || annot || (field && field->alt_ui_name))
@@ -4422,7 +4516,7 @@ ev_view_scroll_event (GtkWidget *widget, GdkEventScroll *event)
        guint state;
        gboolean fit_width, fit_height;
 
-       _ev_view_cleanup_link_preview_popover (view);
+       ev_view_link_preview_popover_cleanup (view);
 
        state = event->state & gtk_accelerator_get_default_mod_mask ();
 
@@ -5152,7 +5246,7 @@ link_preview_job_finished_cb (EvJobThumbnail *job,
 }
 
 static void
-_ev_view_cleanup_link_preview_popover (EvView *view) {
+ev_view_link_preview_popover_cleanup (EvView *view) {
        if (view->link_preview.job) {
                ev_job_cancel (view->link_preview.job);
                g_object_unref (view->link_preview.job);
@@ -5206,102 +5300,18 @@ ev_view_query_tooltip (GtkWidget  *widget,
        }
 
        link = ev_view_get_link_at_location (view, x, y);
-
-       if (!link) {
-               _ev_view_cleanup_link_preview_popover (view);
-               view->link_preview.link = NULL;
+       if (!link)
                return FALSE;
-       }
 
        text = tip_from_link (view, link);
        if (text && g_utf8_validate (text, -1, NULL)) {
-               GdkRectangle     link_area;
-               EvLinkAction    *action;
-               EvLinkDest      *dest;
-               EvLinkDestType   type;
-               EvPoint          link_dest_doc;
-               GdkPoint         link_dest_view;
-               guint            link_dest_page;
-               GtkWidget       *popover, *spinner;
-               cairo_surface_t *page_surface = NULL;
+               GdkRectangle link_area;
 
                get_link_area (view, x, y, link, &link_area);
                gtk_tooltip_set_text (tooltip, text);
                gtk_tooltip_set_tip_area (tooltip, &link_area);
                g_free (text);
 
-               if (link == view->link_preview.link)
-                       return TRUE;
-
-               /* Display thumbnail, if applicable */
-               action = ev_link_get_action (link);
-               if (!action) return TRUE;
-               dest = ev_link_action_get_dest (action);
-               if (!dest) return TRUE;
-               type = ev_link_dest_get_dest_type (dest);
-
-               if (type == EV_LINK_DEST_TYPE_NAMED) {
-                       dest = ev_document_links_find_link_dest (EV_DOCUMENT_LINKS (view->document),
-                                                                ev_link_dest_get_named_dest (dest));
-               }
-
-               _ev_view_cleanup_link_preview_popover (view);
-
-               /* Init popover */
-               view->link_preview.popover = popover = gtk_popover_new (GTK_WIDGET (view));
-               gtk_popover_set_pointing_to (GTK_POPOVER (popover), &link_area);
-               gtk_popover_set_modal (GTK_POPOVER (popover), FALSE);
-
-               spinner = gtk_spinner_new ();
-               gtk_spinner_start (GTK_SPINNER (spinner));
-               gtk_container_add (GTK_CONTAINER (popover) , spinner);
-               gtk_widget_show (spinner);
-
-               /* Start thumbnailing job async */
-               link_dest_page = ev_link_dest_get_page (dest);
-               view->link_preview.job = ev_job_thumbnail_new (view->document,
-                                                              link_dest_page,
-                                                              view->rotation,
-                                                              view->scale);
-               ev_job_thumbnail_set_output_format (EV_JOB_THUMBNAIL (view->link_preview.job),
-                                                   EV_JOB_THUMBNAIL_SURFACE);
-
-               link_dest_doc.x = ev_link_dest_get_left (dest, NULL);
-               link_dest_doc.y = ev_link_dest_get_top (dest, NULL);
-               _ev_view_transform_doc_point_by_rotation_scale (view,
-                                                               link_dest_page,
-                                                               &link_dest_doc,
-                                                               &link_dest_view);
-               view->link_preview.left = link_dest_view.x;
-               view->link_preview.top = link_dest_view.y;
-               view->link_preview.link = link;
-
-               page_surface = ev_pixbuf_cache_get_surface (view->pixbuf_cache,
-                                                           link_dest_page);
-
-               if (page_surface) {
-                       GdkPixbuf *slice;
-
-                       slice = gdk_pixbuf_get_from_surface (page_surface, 0, 0,
-                                      cairo_image_surface_get_width (page_surface),
-                                      cairo_image_surface_get_height (page_surface));
-                       link_preview_show_thumbnail (slice, view);
-
-                       g_object_unref (slice);
-               }
-               else {
-                       g_signal_connect (view->link_preview.job, "finished",
-                                         G_CALLBACK (link_preview_job_finished_cb),
-                                         view);
-                       ev_job_scheduler_push_job (view->link_preview.job,
-                                                  EV_JOB_PRIORITY_LOW);
-               }
-
-               if (type == EV_LINK_DEST_TYPE_NAMED)
-                       g_object_unref (dest);
-
-               gtk_widget_show (popover);
-
                return TRUE;
        }
        g_free (text);
@@ -5500,7 +5510,7 @@ ev_view_button_press_event (GtkWidget      *widget,
 {
        EvView *view = EV_VIEW (widget);
 
-       _ev_view_cleanup_link_preview_popover (view);
+       ev_view_link_preview_popover_cleanup (view);
 
        if (!view->document || ev_document_get_n_pages (view->document) <= 0)
                return FALSE;
@@ -7017,7 +7027,7 @@ ev_view_key_press_event (GtkWidget   *widget,
        EvView  *view = EV_VIEW (widget);
        gboolean retval;
 
-       _ev_view_cleanup_link_preview_popover (view);
+       ev_view_link_preview_popover_cleanup (view);
 
        if (!view->document)
                return FALSE;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]