# HG changeset patch # User Thomas Liebetraut # Date 1396178635 -7200 # Sun Mar 30 13:23:55 2014 +0200 # Node ID b57f18696badeb88f1032db9e2dd2b577d606b0d # Parent b8bcc5b4217c48ebe222ef43e53d93be1e617818 Add support for interactive areas in annotations. Some annotation types do not have a rectangular shape and require non-rectangular boundary checks to determine if the user clicked on them. A new method ev_annotation_is_location_in_area() is added that determines whether a point location is actually inside the annotation's interactive area. diff -r b8bcc5b4217c -r b57f18696bad libdocument/ev-annotation.c --- a/libdocument/ev-annotation.c Sun Mar 30 13:23:55 2014 +0200 +++ b/libdocument/ev-annotation.c Sun Mar 30 13:23:55 2014 +0200 @@ -40,6 +40,10 @@ struct _EvAnnotationClass { GObjectClass parent_class; + + gboolean (* is_location_in_area) (EvAnnotation *annot, + gdouble x, + gdouble y); }; struct _EvAnnotationMarkupInterface { @@ -152,6 +156,26 @@ annot->type = EV_ANNOTATION_TYPE_UNKNOWN; } +static gboolean +ev_annotation_impl_is_location_in_area (EvAnnotation *annot, + gdouble x, + gdouble y) +{ + g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE); + + /* fall back to bound rectangle */ + EvRectangle rect; + ev_annotation_get_bounding_rectangle (annot, &rect); + if ((x >= rect.x1) && + (x <= rect.x2) && + (y >= rect.y1) && + (y <= rect.y2)) { + return TRUE; + } + + return FALSE; +} + static void ev_annotation_set_property (GObject *object, guint prop_id, @@ -228,6 +252,8 @@ { GObjectClass *g_object_class = G_OBJECT_CLASS (klass); + klass->is_location_in_area = ev_annotation_impl_is_location_in_area; + g_object_class->finalize = ev_annotation_finalize; g_object_class->set_property = ev_annotation_set_property; g_object_class->get_property = ev_annotation_get_property; @@ -684,6 +710,19 @@ return TRUE; } +gboolean +ev_annotation_is_location_in_area (EvAnnotation *annot, + gdouble x, + gdouble y) +{ + g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE); + + EvAnnotationClass *klass = EV_ANNOTATION_GET_CLASS (annot); + + return klass->is_location_in_area (annot, x, y); +} + + /* EvAnnotationMarkup */ typedef struct { gchar *label; diff -r b8bcc5b4217c -r b57f18696bad libdocument/ev-annotation.h --- a/libdocument/ev-annotation.h Sun Mar 30 13:23:55 2014 +0200 +++ b/libdocument/ev-annotation.h Sun Mar 30 13:23:55 2014 +0200 @@ -129,6 +129,9 @@ EvRectangle *rect); gboolean ev_annotation_set_bounding_rectangle (EvAnnotation *annot, const EvRectangle *rect); +gboolean ev_annotation_is_location_in_area (EvAnnotation *annot, + gdouble x, + gdouble y); /* EvAnnotationMarkup */ GType ev_annotation_markup_get_type (void) G_GNUC_CONST; diff -r b8bcc5b4217c -r b57f18696bad libdocument/ev-mapping-list.c --- a/libdocument/ev-mapping-list.c Sun Mar 30 13:23:55 2014 +0200 +++ b/libdocument/ev-mapping-list.c Sun Mar 30 13:23:55 2014 +0200 @@ -19,6 +19,7 @@ */ #include "ev-mapping-list.h" +#include "ev-annotation.h" /** * SECTION: ev-mapping-list @@ -121,10 +122,15 @@ for (list = mapping_list->list; list; list = list->next) { EvMapping *mapping = list->data; - if ((x >= mapping->area.x1) && - (y >= mapping->area.y1) && - (x <= mapping->area.x2) && - (y <= mapping->area.y2)) { + if (EV_IS_ANNOTATION(mapping->data)) { + if (ev_annotation_is_location_in_area ( + EV_ANNOTATION(mapping->data), x, y)) { + return mapping; + } + } else if ((x >= mapping->area.x1) && + (y >= mapping->area.y1) && + (x <= mapping->area.x2) && + (y <= mapping->area.y2)) { return mapping; } }