[evince] libview: Implement support for moving text annotations.
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince] libview: Implement support for moving text annotations.
- Date: Sat, 20 Jun 2015 09:14:58 +0000 (UTC)
commit 3439819eb1ac4b50ee10e92c4fb09e4fd696f01e
Author: Philipp Reinkemeier <philipp reinkemeier offis de>
Date: Tue Jun 9 10:00:10 2015 +0200
libview: Implement support for moving text annotations.
This adds support for moving text annotations by simply
dragging them to a new location.
The call to ev_view_handle_annotation has been moved from callback
ev_view_button_press_event to ev_view_button_release_event.
https://bugzilla.gnome.org/show_bug.cgi?id=649043
libview/ev-view-private.h | 9 +++
libview/ev-view.c | 121 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 129 insertions(+), 1 deletions(-)
---
diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h
index 5d4537d..a6862b1 100644
--- a/libview/ev-view-private.h
+++ b/libview/ev-view-private.h
@@ -122,6 +122,14 @@ typedef struct {
EvAnnotation *annot;
} AddingAnnotInfo;
+typedef struct {
+ GdkPoint start;
+ EvPoint cursor_offset;
+ gboolean annot_clicked;
+ gboolean moving_annot;
+ EvAnnotation *annot;
+} MovingAnnotInfo;
+
struct _EvView {
GtkContainer layout;
@@ -217,6 +225,7 @@ struct _EvView {
GList *window_children;
EvViewWindowChild *window_child_focus;
AddingAnnotInfo adding_annot_info;
+ MovingAnnotInfo moving_annot_info;
/* Focus */
EvMapping *focused_element;
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 9e5e0e0..6f2876d 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -5006,7 +5006,42 @@ ev_view_button_press_event (GtkWidget *widget,
} else if ((media = ev_view_get_media_at_location (view, event->x, event->y))) {
ev_view_handle_media (view, media);
} else if ((annot = ev_view_get_annotation_at_location (view, event->x, event->y))) {
- ev_view_handle_annotation (view, annot, event->x, event->y, event->time);
+ if (EV_IS_ANNOTATION_TEXT (annot)) {
+ EvRectangle current_area;
+ GdkPoint view_point;
+ EvPoint doc_point;
+ GdkRectangle page_area;
+ GtkBorder border;
+ guint annot_page;
+
+ /* annot_clicked remembers that we clicked
+ * on an annotation. We need moving_annot
+ * to distinguish moving an annotation from
+ * showing its popup upon button release. */
+ view->moving_annot_info.annot_clicked = TRUE;
+ view->moving_annot_info.moving_annot = FALSE;
+ view->moving_annot_info.annot = annot;
+ ev_annotation_get_area (annot, ¤t_area);
+
+ view_point.x = event->x + view->scroll_x;
+ view_point.y = event->y + view->scroll_y;
+
+ /* Remember the coordinates of the button press event
+ * in order to implement a minimum threshold for moving
+ * annotations. */
+ view->moving_annot_info.start = view_point;
+ annot_page = ev_annotation_get_page_index (annot);
+ ev_view_get_page_extents (view, annot_page, &page_area, &border);
+ _ev_view_transform_view_point_to_doc_point (view, &view_point,
+ &page_area, &border,
+ &doc_point.x,
&doc_point.y);
+
+ /* Remember the offset of the cursor with respect to
+ * the annotation area in order to prevent the annotation from
+ * jumping under the cursor while moving it. */
+ view->moving_annot_info.cursor_offset.x = doc_point.x -
current_area.x1;
+ view->moving_annot_info.cursor_offset.y = doc_point.y -
current_area.y1;
+ }
} else if ((field = ev_view_get_form_field_at_location (view, event->x, event->y))) {
ev_view_remove_all_form_fields (view);
ev_view_handle_form_field (view, field);
@@ -5406,6 +5441,69 @@ ev_view_motion_notify_event (GtkWidget *widget,
/* FIXME: reload only annotation area */
ev_view_reload_page (view, annot_page, NULL);
+ } else if (view->moving_annot_info.annot_clicked) {
+ EvRectangle rect;
+ EvRectangle current_area;
+ GdkPoint view_point;
+ EvPoint doc_point;
+ GdkRectangle page_area;
+ GtkBorder border;
+ guint annot_page;
+ double page_width;
+ double page_height;
+
+ if (!view->moving_annot_info.annot)
+ return TRUE;
+
+ view_point.x = event->x + view->scroll_x;
+ view_point.y = event->y + view->scroll_y;
+
+ if (!view->moving_annot_info.moving_annot) {
+ /* Only move the annotation if the threshold is exceeded */
+ if (!gtk_drag_check_threshold (widget,
+ view->moving_annot_info.start.x,
+ view->moving_annot_info.start.y,
+ view_point.x,
+ view_point.y))
+ return TRUE;
+ view->moving_annot_info.moving_annot = TRUE;
+ }
+
+ ev_annotation_get_area (view->moving_annot_info.annot, ¤t_area);
+ annot_page = ev_annotation_get_page_index (view->moving_annot_info.annot);
+ ev_view_get_page_extents (view, annot_page, &page_area, &border);
+ _ev_view_transform_view_point_to_doc_point (view, &view_point, &page_area, &border,
+ &doc_point.x, &doc_point.y);
+
+ ev_document_get_page_size (view->document, annot_page, &page_width, &page_height);
+
+ rect.x1 = MAX (0, doc_point.x - view->moving_annot_info.cursor_offset.x);
+ rect.y1 = MAX (0, doc_point.y - view->moving_annot_info.cursor_offset.y);
+ rect.x2 = rect.x1 + current_area.x2 - current_area.x1;
+ rect.y2 = rect.y1 + current_area.y2 - current_area.y1;
+
+ /* Prevent the annotation from being moved off the page */
+ if (rect.x2 > page_width) {
+ rect.x2 = page_width;
+ rect.x1 = page_width - current_area.x2 + current_area.x1;
+ }
+ if (rect.y2 > page_height) {
+ rect.y2 = page_height;
+ rect.y1 = page_height - current_area.y2 + current_area.y1;
+ }
+
+ /* Take the mutex before set_area, because the notify signal
+ * updates the mappings in the backend */
+ ev_document_doc_mutex_lock ();
+ if (ev_annotation_set_area (view->moving_annot_info.annot, &rect)) {
+ ev_document_annotations_save_annotation (EV_DOCUMENT_ANNOTATIONS
(view->document),
+ view->moving_annot_info.annot,
+ EV_ANNOTATIONS_SAVE_AREA);
+ }
+ ev_document_doc_mutex_unlock ();
+
+ /* FIXME: reload only annotation area */
+ ev_view_reload_page (view, annot_page, NULL);
} else {
/* Schedule timeout to scroll during selection and additionally
* scroll once to allow arbitrary speed. */
@@ -5589,6 +5687,27 @@ ev_view_button_release_event (GtkWidget *widget,
return FALSE;
}
+ if (view->moving_annot_info.annot_clicked) {
+ if (view->moving_annot_info.moving_annot)
+ ev_view_handle_cursor_over_xy (view, event->x, event->y);
+ else
+ ev_view_handle_annotation (view, view->moving_annot_info.annot, event->x, event->y,
event->time);
+
+ view->moving_annot_info.annot_clicked = FALSE;
+ view->moving_annot_info.moving_annot = FALSE;
+ view->moving_annot_info.annot = NULL;
+ view->pressed_button = -1;
+
+ return FALSE;
+ }
+
+ if (view->pressed_button == 1) {
+ EvAnnotation *annot = ev_view_get_annotation_at_location (view, event->x, event->y);
+
+ if (annot)
+ ev_view_handle_annotation (view, annot, event->x, event->y, event->time);
+ }
+
if (view->pressed_button == 2) {
ev_view_handle_cursor_over_xy (view, event->x, event->y);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]