[evince] view: preparing for interactive annotations



commit 5ed7b5f6b1a40625ae989821cafc75ac6b5b7065
Author: Giselle Machado <gisellemnr src gnome org>
Date:   Fri Jul 25 23:35:37 2014 +0200

    view: preparing for interactive annotations
    
    Added a struct to the view that holds start and
    end points of annotations in order to support
    'click and drag' annotations.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=583377

 libview/ev-view-private.h |   12 ++++-
 libview/ev-view.c         |  119 +++++++++++++++++++++++++-------------------
 2 files changed, 78 insertions(+), 53 deletions(-)
---
diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h
index 087f3ef..5d4537d 100644
--- a/libview/ev-view-private.h
+++ b/libview/ev-view-private.h
@@ -113,6 +113,15 @@ typedef struct _EvHeightToPageCache {
        gdouble *dual_height_to_page;
 } EvHeightToPageCache;
 
+/* Information for handling annotations */
+typedef struct {
+       GdkPoint         start;
+       GdkPoint         stop;
+       gboolean         adding_annot;
+       EvAnnotationType type;
+       EvAnnotation    *annot;
+} AddingAnnotInfo;
+
 struct _EvView {
        GtkContainer layout;
 
@@ -207,8 +216,7 @@ struct _EvView {
        /* Annotations */
        GList             *window_children;
        EvViewWindowChild *window_child_focus;
-       gboolean           adding_annot;
-       EvAnnotationType   adding_annot_type;
+       AddingAnnotInfo    adding_annot_info;
 
        /* Focus */
        EvMapping *focused_element;
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 0ddf1a1..e787fdf 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -115,6 +115,7 @@ typedef struct {
 
 #define ANNOT_POPUP_WINDOW_DEFAULT_WIDTH  200
 #define ANNOT_POPUP_WINDOW_DEFAULT_HEIGHT 150
+#define ANNOTATION_ICON_SIZE 24
 
 /*** Scrolling ***/
 static void       view_update_range_and_current_page         (EvView             *view);
@@ -2094,7 +2095,7 @@ ev_view_handle_cursor_over_xy (EvView *view, gint x, gint y)
        if (view->cursor == EV_VIEW_CURSOR_HIDDEN)
                return;
 
-       if (view->adding_annot) {
+       if (view->adding_annot_info.adding_annot && !view->adding_annot_info.annot) {
                if (view->cursor != EV_VIEW_CURSOR_ADD)
                        ev_view_set_cursor (view, EV_VIEW_CURSOR_ADD);
                return;
@@ -3294,13 +3295,11 @@ ev_view_handle_annotation (EvView       *view,
 }
 
 static void
-ev_view_create_annotation (EvView          *view,
-                          EvAnnotationType annot_type,
-                          gint             x,
-                          gint             y)
+ev_view_create_annotation (EvView *view)
 {
        EvAnnotation   *annot;
-       GdkPoint        point;
+       EvPoint         start;
+       EvPoint         end;
        GdkRectangle    page_area;
        GtkBorder       border;
        EvRectangle     doc_rect, popup_rect;
@@ -3309,20 +3308,22 @@ ev_view_create_annotation (EvView          *view,
        GdkRectangle    view_rect;
        cairo_region_t *region;
 
-       point.x = x;
-       point.y = y;
        ev_view_get_page_extents (view, view->current_page, &page_area, &border);
-       _ev_view_transform_view_point_to_doc_point (view, &point, &page_area, &border,
-                                                   &doc_rect.x1, &doc_rect.y1);
-       doc_rect.x2 = doc_rect.x1 + 24;
-       doc_rect.y2 = doc_rect.y1 + 24;
+       _ev_view_transform_view_point_to_doc_point (view, &view->adding_annot_info.start, &page_area, &border,
+                                                   &start.x, &start.y);
+       _ev_view_transform_view_point_to_doc_point (view, &view->adding_annot_info.stop, &page_area, &border,
+                                                   &end.x, &end.y);
 
        ev_document_doc_mutex_lock ();
        page = ev_document_get_page (view->document, view->current_page);
-       switch (annot_type) {
-       case EV_ANNOTATION_TYPE_TEXT:
-               annot = ev_annotation_text_new (page);
-               break;
+        switch (view->adding_annot_info.type) {
+        case EV_ANNOTATION_TYPE_TEXT:
+                doc_rect.x1 = end.x;
+                doc_rect.y1 = end.y;
+                doc_rect.x2 = doc_rect.x1 + ANNOTATION_ICON_SIZE;
+                doc_rect.y2 = doc_rect.y1 + ANNOTATION_ICON_SIZE;
+                annot = ev_annotation_text_new (page);
+                break;
        case EV_ANNOTATION_TYPE_ATTACHMENT:
                /* TODO */
                g_object_unref (page);
@@ -3374,7 +3375,8 @@ ev_view_create_annotation (EvView          *view,
        ev_view_reload_page (view, view->current_page, region);
        cairo_region_destroy (region);
 
-       g_signal_emit (view, signals[SIGNAL_ANNOT_ADDED], 0, annot);
+       view->adding_annot_info.annot = annot;
+       ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL);
 }
 
 void
@@ -3396,11 +3398,11 @@ ev_view_begin_add_annotation (EvView          *view,
        if (annot_type == EV_ANNOTATION_TYPE_UNKNOWN)
                return;
 
-       if (view->adding_annot)
+       if (view->adding_annot_info.adding_annot)
                return;
 
-       view->adding_annot = TRUE;
-       view->adding_annot_type = annot_type;
+       view->adding_annot_info.adding_annot = TRUE;
+       view->adding_annot_info.type = annot_type;
        ev_view_set_cursor (view, EV_VIEW_CURSOR_ADD);
 }
 
@@ -3409,10 +3411,11 @@ ev_view_cancel_add_annotation (EvView *view)
 {
        gint x, y;
 
-       if (!view->adding_annot)
+       if (!view->adding_annot_info.adding_annot)
                return;
 
-       view->adding_annot = FALSE;
+       view->adding_annot_info.adding_annot = FALSE;
+       g_assert(!view->adding_annot_info.annot);
        ev_document_misc_get_pointer_position (GTK_WIDGET (view), &x, &y);
        ev_view_handle_cursor_over_xy (view, x, y);
 }
@@ -4942,12 +4945,21 @@ ev_view_button_press_event (GtkWidget      *widget,
        view->pressed_button = event->button;
        view->selection_info.in_drag = FALSE;
 
-       if (view->adding_annot)
-               return FALSE;
-
        if (view->scroll_info.autoscrolling)
                return TRUE;
 
+       if (view->adding_annot_info.adding_annot && !view->adding_annot_info.annot) {
+               if (event->button != 1)
+                       return TRUE;
+
+               view->adding_annot_info.start.x = event->x + view->scroll_x;
+               view->adding_annot_info.start.y = event->y + view->scroll_y;
+               view->adding_annot_info.stop = view->adding_annot_info.start;
+               ev_view_create_annotation (view);
+
+               return TRUE;
+       }
+
        switch (event->button) {
                case 1: {
                        EvImage *image;
@@ -5330,25 +5342,27 @@ ev_view_motion_notify_event (GtkWidget      *widget,
                if (view->rotation != 0)
                        return FALSE;
 
-               /* Schedule timeout to scroll during selection and additionally 
-                * scroll once to allow arbitrary speed. */
-               if (!view->selection_scroll_id)
-                   view->selection_scroll_id = g_timeout_add (SCROLL_TIME,
-                                                              (GSourceFunc)selection_scroll_timeout_cb,
-                                                              view);
-               else 
-                   selection_scroll_timeout_cb (view);
-
-               view->motion.x = x + view->scroll_x;
-               view->motion.y = y + view->scroll_y;
-
-               /* Queue an idle to handle the motion.  We do this because      
-                * handling any selection events in the motion could be slower  
-                * than new motion events reach us.  We always put it in the    
-                * idle to make sure we catch up and don't visibly lag the      
-                * mouse. */
-               if (!view->selection_update_id)
-                       view->selection_update_id = g_idle_add ((GSourceFunc)selection_update_idle_cb, view);
+               if (!view->adding_annot_info.adding_annot) {
+                       /* Schedule timeout to scroll during selection and additionally
+                        * scroll once to allow arbitrary speed. */
+                       if (!view->selection_scroll_id)
+                               view->selection_scroll_id = g_timeout_add (SCROLL_TIME,
+                                                                          
(GSourceFunc)selection_scroll_timeout_cb,
+                                                                          view);
+                       else
+                               selection_scroll_timeout_cb (view);
+
+                       view->motion.x = x + view->scroll_x;
+                       view->motion.y = y + view->scroll_y;
+
+                       /* Queue an idle to handle the motion.  We do this because
+                        * handling any selection events in the motion could be slower
+                        * than new motion events reach us.  We always put it in the
+                        * idle to make sure we catch up and don't visibly lag the
+                        * mouse. */
+                       if (!view->selection_update_id)
+                               view->selection_update_id = g_idle_add 
((GSourceFunc)selection_update_idle_cb, view);
+               }
 
                return TRUE;
        case 2:
@@ -5449,16 +5463,19 @@ ev_view_button_release_event (GtkWidget      *widget,
 
        view->drag_info.in_drag = FALSE;
 
-       if (view->adding_annot && view->pressed_button == 1) {
-               view->adding_annot = FALSE;
+       if (view->adding_annot_info.adding_annot) {
+               g_assert (view->pressed_button == 1);
+               g_assert (view->adding_annot_info.annot);
+
+               view->adding_annot_info.stop.x = event->x + view->scroll_x;
+               view->adding_annot_info.stop.y = event->y + view->scroll_y;
+               g_signal_emit (view, signals[SIGNAL_ANNOT_ADDED], 0, view->adding_annot_info.annot);
+
+               view->adding_annot_info.adding_annot = FALSE;
+               view->adding_annot_info.annot = NULL;
                ev_view_handle_cursor_over_xy (view, event->x, event->y);
                view->pressed_button = -1;
 
-               ev_view_create_annotation (view,
-                                          view->adding_annot_type,
-                                          event->x + view->scroll_x,
-                                          event->y + view->scroll_y);
-
                return FALSE;
        }
 


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