[cairo-commit] goocanvas/src goocanvas.c, 1.10, 1.11 goocanvas.h, 1.7, 1.8 goocanvasgroup.c, 1.21, 1.22 goocanvasimage.c, 1.14, 1.15 goocanvasitem.c, 1.20, 1.21 goocanvasitem.h, 1.13, 1.14 goocanvasitemsimple.c, 1.25, 1.26 goocanvasitemsimple.h, 1.18, 1.19 goocanvaspolyline.c, 1.13, 1.14 goocanvastable.c, 1.9, 1.10 goocanvastext.c, 1.15, 1.16 goocanvaswidget.c, 1.6, 1.7

Damon Chaplin commit at pdx.freedesktop.org
Mon Feb 26 17:01:46 PST 2007


Committed by: damon

Update of /cvs/cairo/goocanvas/src
In directory kemper:/tmp/cvs-serv19936/src

Modified Files:
	goocanvas.c goocanvas.h goocanvasgroup.c goocanvasimage.c 
	goocanvasitem.c goocanvasitem.h goocanvasitemsimple.c 
	goocanvasitemsimple.h goocanvaspolyline.c goocanvastable.c 
	goocanvastext.c goocanvaswidget.c 
Log Message:
2007-02-27  Damon Chaplin  <damon at gnome.org>

	* src/goocanvasitem.[hc]: changed get_item_at method to get_items_at
	which returns a list of found items rather than a single found item.

	* src/goocanvasitemsimple.[hc]: changed get_item_at() method to
	is_item_at() which just returns a boolean, and updated to new API.

	* src/goocanvas.c (goo_canvas_get_item_at): updated to use new API.
	(goo_canvas_get_items_at): new function to return list of found items.

	* src/goocanvastable.c (goo_canvas_table_get_items_at): 
	* src/goocanvasgroup.c (goo_canvas_group_get_items_at):
	* src/goocanvasimage.c (goo_canvas_image_is_item_at): 
	* src/goocanvaspolyline.c (goo_canvas_polyline_is_item_at): 
	* src/goocanvastext.c (goo_canvas_text_is_item_at): 
	* src/goocanvaswidget.c (goo_canvas_widget_is_item_at): 
	* docs/creating-items.xml: 
	* demo/demo-item.c (goo_demo_item_is_item_at): updated for new API.



Index: goocanvas.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvas.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- goocanvas.c	25 Feb 2007 17:57:38 -0000	1.10
+++ goocanvas.c	27 Feb 2007 01:01:39 -0000	1.11
@@ -811,7 +811,7 @@
  * 
  * Gets the item at the given point.
  * 
- * Returns: the item found at the given point, or %NULL if no item  was found.
+ * Returns: the item found at the given point, or %NULL if no item was found.
  **/
 GooCanvasItem*
 goo_canvas_get_item_at (GooCanvas     *canvas,
@@ -820,18 +820,60 @@
 			gboolean       is_pointer_event)
 {
   cairo_t *cr;
-  GooCanvasItem *found;
+  GooCanvasItem *result = NULL;
+  GList *list;
 
-  /* If no canvas model is set, just return NULL. */
+  /* If no root item is set, just return NULL. */
   if (!canvas->root_item)
     return NULL;
 
   cr = goo_canvas_create_cairo (canvas);
-  found = goo_canvas_item_get_item_at (canvas->root_item, x, y, cr,
-				       is_pointer_event, TRUE);
+  list = goo_canvas_item_get_items_at (canvas->root_item, x, y, cr,
+				       is_pointer_event, TRUE, NULL);
   cairo_destroy (cr);
 
-  return found;
+  /* We just return the top item in the list. */
+  if (list)
+    result = list->data;
+
+  g_list_free (list);
+
+  return result;
+}
+
+
+/**
+ * goo_canvas_get_items_at:
+ * @canvas: a #GooCanvas.
+ * @x: the x coordinate of the point.
+ * @y: the y coordinate of the point
+ * @is_pointer_event: %TRUE if the "pointer-events" property of
+ *  items should be used to determine which parts of the item are tested.
+ * 
+ * Gets all items at the given point.
+ * 
+ * Returns: a list of items found at the given point, with the top item at
+ *  the start of the list, or %NULL if no items were found.
+ **/
+GList*
+goo_canvas_get_items_at (GooCanvas     *canvas,
+			 gdouble        x,
+			 gdouble        y,
+			 gboolean       is_pointer_event)
+{
+  cairo_t *cr;
+  GList *result;
+
+  /* If no root item is set, just return NULL. */
+  if (!canvas->root_item)
+    return NULL;
+
+  cr = goo_canvas_create_cairo (canvas);
+  result = goo_canvas_item_get_items_at (canvas->root_item, x, y, cr,
+					 is_pointer_event, TRUE, NULL);
+  cairo_destroy (cr);
+
+  return result;
 }
 
 
@@ -2089,14 +2131,9 @@
     {
       double x = canvas->crossing_event.x;
       double y = canvas->crossing_event.y;
-      cairo_t *cr;
 
       goo_canvas_convert_from_pixels (canvas, &x, &y);
-
-      cr = goo_canvas_create_cairo (canvas);
-      new_item = goo_canvas_item_get_item_at (canvas->root_item, x, y, cr,
-					      TRUE, TRUE);
-      cairo_destroy (cr);
+      new_item = goo_canvas_get_item_at (canvas, x, y, TRUE);
     }
 
   /* If the current item hasn't changed, just return. */

Index: goocanvas.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvas.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- goocanvas.h	13 Feb 2007 12:39:57 -0000	1.7
+++ goocanvas.h	27 Feb 2007 01:01:39 -0000	1.8
@@ -182,6 +182,10 @@
 					     gdouble             x,
 					     gdouble             y,
 					     gboolean            is_pointer_event);
+GList*		goo_canvas_get_items_at	    (GooCanvas		*canvas,
+					     gdouble		 x,
+					     gdouble		 y,
+					     gboolean		 is_pointer_event);
 
 gdouble         goo_canvas_get_scale	    (GooCanvas		*canvas);
 void            goo_canvas_set_scale	    (GooCanvas		*canvas,

Index: goocanvasgroup.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasgroup.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- goocanvasgroup.c	25 Feb 2007 17:37:57 -0000	1.21
+++ goocanvasgroup.c	27 Feb 2007 01:01:39 -0000	1.22
@@ -406,18 +406,18 @@
 }
 
 
-static GooCanvasItem*
-goo_canvas_group_get_item_at (GooCanvasItem  *item,
-			      gdouble         x,
-			      gdouble         y,
-			      cairo_t        *cr,
-			      gboolean        is_pointer_event,
-			      gboolean        parent_visible)
+static GList*
+goo_canvas_group_get_items_at (GooCanvasItem  *item,
+			       gdouble         x,
+			       gdouble         y,
+			       cairo_t        *cr,
+			       gboolean        is_pointer_event,
+			       gboolean        parent_visible,
+			       GList          *found_items)
 {
   GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
   GooCanvasItemSimpleData *simple_data = simple->simple_data;
   GooCanvasGroup *group = (GooCanvasGroup*) item;
-  GooCanvasItem *found_item = NULL;
   gboolean visible = parent_visible;
   int i;
 
@@ -427,7 +427,7 @@
   /* Skip the item if the point isn't in the item's bounds. */
   if (simple->bounds.x1 > x || simple->bounds.x2 < x
       || simple->bounds.y1 > y || simple->bounds.y2 < y)
-    return NULL;
+    return found_items;
 
   if (simple_data->visibility <= GOO_CANVAS_ITEM_INVISIBLE
       || (simple_data->visibility == GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD
@@ -439,10 +439,8 @@
       && (simple_data->pointer_events == GOO_CANVAS_EVENTS_NONE
 	  || ((simple_data->pointer_events & GOO_CANVAS_EVENTS_VISIBLE_MASK)
 	      && !visible)))
-    return NULL;
+    return found_items;
 
-  /* Step down from the top item to the bottom in the stack/layer, and return
-     the first item found that contains the given point. */
   cairo_save (cr);
   if (simple_data->transform)
     cairo_transform (cr, simple_data->transform);
@@ -458,22 +456,23 @@
       if (!cairo_in_fill (cr, user_x, user_y))
 	{
 	  cairo_restore (cr);
-	  return NULL;
+	  return found_items;
 	}
     }
 
-  for (i = group->items->len - 1; i >= 0; i--)
+  /* Step up from the bottom of the children to the top, adding any items
+     found to the start of the list. */
+  for (i = 0; i < group->items->len; i++)
     {
       GooCanvasItem *child = group->items->pdata[i];
 
-      found_item = goo_canvas_item_get_item_at (child, x, y, cr,
-						is_pointer_event, visible);
-      if (found_item)
-	break;
+      found_items = goo_canvas_item_get_items_at (child, x, y, cr,
+						  is_pointer_event, visible,
+						  found_items);
     }
   cairo_restore (cr);
 
-  return found_item;
+  return found_items;
 }
 
 
@@ -533,7 +532,7 @@
   iface->move_child     = goo_canvas_group_move_child;
   iface->remove_child   = goo_canvas_group_remove_child;
 
-  iface->get_item_at	= goo_canvas_group_get_item_at;
+  iface->get_items_at	= goo_canvas_group_get_items_at;
   iface->update         = goo_canvas_group_update;
   iface->paint          = goo_canvas_group_paint;
 

Index: goocanvasimage.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasimage.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- goocanvasimage.c	25 Feb 2007 17:37:57 -0000	1.14
+++ goocanvasimage.c	27 Feb 2007 01:01:39 -0000	1.15
@@ -327,21 +327,21 @@
 }
 
 
-static GooCanvasItem*
-goo_canvas_image_get_item_at (GooCanvasItemSimple *simple,
-			      gdouble              x,
-			      gdouble              y,
-			      cairo_t             *cr,
-			      gboolean             is_pointer_event)
+static gboolean
+goo_canvas_image_is_item_at (GooCanvasItemSimple *simple,
+			     gdouble              x,
+			     gdouble              y,
+			     cairo_t             *cr,
+			     gboolean             is_pointer_event)
 {
   GooCanvasImage *image = (GooCanvasImage*) simple;
   GooCanvasImageData *image_data = image->image_data;
 
   if (x < image_data->x || (x > image_data->x + image_data->width)
       || y < image_data->y || (y > image_data->y + image_data->height))
-    return NULL;
+    return FALSE;
 
-  return (GooCanvasItem*) simple;
+  return TRUE;
 }
 
 
@@ -429,7 +429,7 @@
 
   simple_class->simple_update      = goo_canvas_image_update;
   simple_class->simple_paint       = goo_canvas_image_paint;
-  simple_class->simple_get_item_at = goo_canvas_image_get_item_at;
+  simple_class->simple_is_item_at  = goo_canvas_image_is_item_at;
 
   goo_canvas_image_install_common_properties (gobject_class);
 }

Index: goocanvasitem.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasitem.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- goocanvasitem.c	17 Feb 2007 13:48:37 -0000	1.20
+++ goocanvasitem.c	27 Feb 2007 01:01:39 -0000	1.21
@@ -1318,7 +1318,7 @@
 
 
 /**
- * goo_canvas_item_get_item_at:
+ * goo_canvas_item_get_items_at:
  * @item: a #GooCanvasItem.
  * @x: the x coordinate of the point.
  * @y: the y coordinate of the point.
@@ -1327,23 +1327,26 @@
  *  be used to determine which parts of the item are tested.
  * @parent_is_visible: %TRUE if the parent item is visible (which
  *  implies that all ancestors are also visible).
+ * @found_items: the list of items found so far.
  * 
- * Gets the item at the given point.
+ * Gets the items at the given point.
  * 
- * Returns: the item found at the given point, or %NULL if no item  was found.
+ * Returns: a list of items found at the given point, with the top item at
+ *  the start of the list, or %NULL if no items were found.
  **/
-GooCanvasItem*
-goo_canvas_item_get_item_at (GooCanvasItem  *item,
-			     gdouble         x,
-			     gdouble         y,
-			     cairo_t        *cr,
-			     gboolean        is_pointer_event,
-			     gboolean        parent_is_visible)
+GList*
+goo_canvas_item_get_items_at (GooCanvasItem  *item,
+			      gdouble         x,
+			      gdouble         y,
+			      cairo_t        *cr,
+			      gboolean        is_pointer_event,
+			      gboolean        parent_is_visible,
+			      GList          *found_items)
 {
   GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
 
-  return iface->get_item_at (item, x, y, cr, is_pointer_event,
-			     parent_is_visible);
+  return iface->get_items_at (item, x, y, cr, is_pointer_event,
+			      parent_is_visible, found_items);
 }
 
 

Index: goocanvasitem.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasitem.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- goocanvasitem.h	13 Feb 2007 12:32:44 -0000	1.13
+++ goocanvasitem.h	27 Feb 2007 01:01:39 -0000	1.14
@@ -91,7 +91,7 @@
  * @get_parent: gets the item's parent.
  * @set_parent: sets the item's parent.
  * @get_bounds: gets the bounds of the item.
- * @get_item_at: gets the item at the given point.
+ * @get_items_at: gets all the items at the given point.
  * @update: updates the item, if needed. It recalculates the bounds of the item
  *  and requests redraws of parts of the canvas if necessary.
  * @paint: renders the item to the given cairo context.
@@ -126,7 +126,7 @@
  * #GooCanvasItem interface.
  *
  * Simple canvas items only need to implement the get_parent(), set_parent(),
- * get_bounds(), get_item_at(), update() and paint() methods (and also
+ * get_bounds(), get_items_at(), update() and paint() methods (and also
  * get_requested_area() and allocate_area() if they are going to be used
  * inside a layout container like #GooCanvasTable).
  *
@@ -187,12 +187,13 @@
 							 GooCanvasItem		*parent);
   void			(* get_bounds)			(GooCanvasItem		*item,
 							 GooCanvasBounds	*bounds);
-  GooCanvasItem*	(* get_item_at)			(GooCanvasItem		*item,
+  GList*		(* get_items_at)		(GooCanvasItem		*item,
 							 gdouble		 x,
 							 gdouble		 y,
 							 cairo_t		*cr,
 							 gboolean		 is_pointer_event,
-							 gboolean		 parent_is_visible);
+							 gboolean		 parent_is_visible,
+							 GList                  *found_items);
   void			(* update)			(GooCanvasItem		*item,
 							 gboolean		 entire_tree,
 							 cairo_t		*cr,
@@ -372,12 +373,13 @@
 
 void               goo_canvas_item_get_bounds	  (GooCanvasItem   *item,
 						   GooCanvasBounds *bounds);
-GooCanvasItem*	   goo_canvas_item_get_item_at    (GooCanvasItem   *item,
+GList*		   goo_canvas_item_get_items_at   (GooCanvasItem   *item,
 						   gdouble          x,
 						   gdouble          y,
 						   cairo_t         *cr,
 						   gboolean         is_pointer_event,
-						   gboolean         parent_is_visible);
+						   gboolean         parent_is_visible,
+						   GList           *found_items);
 gboolean           goo_canvas_item_is_visible     (GooCanvasItem   *item);
 
 GooCanvasItemModel* goo_canvas_item_get_model	  (GooCanvasItem      *item);

Index: goocanvasitemsimple.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasitemsimple.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- goocanvasitemsimple.c	25 Feb 2007 18:25:52 -0000	1.25
+++ goocanvasitemsimple.c	27 Feb 2007 01:01:39 -0000	1.26
@@ -22,7 +22,7 @@
  * method. (#GooCanvasEllipse, #GooCanvasRect and #GooCanvasPath do this.)
  *
  * More complicated items need to implement the update(), paint() and
- * get_item_at() methods. (#GooCanvasImage, #GooCanvasPolyline,
+ * is_item_at() methods. (#GooCanvasImage, #GooCanvasPolyline,
  * #GooCanvasText and #GooCanvasWidget do this.) They may also need to
  * override some of the other GooCanvasItem methods such as set_canvas(),
  * set_parent() or allocate_area() if special code is needed. (#GooCanvasWidget
@@ -950,21 +950,22 @@
 }
 
 
-static GooCanvasItem*
-goo_canvas_item_simple_get_item_at (GooCanvasItem  *item,
-				    gdouble         x,
-				    gdouble         y,
-				    cairo_t        *cr,
-				    gboolean        is_pointer_event,
-				    gboolean        parent_visible)
+static GList*
+goo_canvas_item_simple_get_items_at (GooCanvasItem  *item,
+				     gdouble         x,
+				     gdouble         y,
+				     cairo_t        *cr,
+				     gboolean        is_pointer_event,
+				     gboolean        parent_visible,
+				     GList          *found_items)
 {
   GooCanvasItemSimpleClass *class = GOO_CANVAS_ITEM_SIMPLE_GET_CLASS (item);
   GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
   GooCanvasItemSimpleData *simple_data = simple->simple_data;
-  GooCanvasItem *found = NULL;
   double user_x = x, user_y = y;
   GooCanvasPointerEvents pointer_events = GOO_CANVAS_EVENTS_ALL;
   cairo_matrix_t matrix;
+  gboolean add_item = FALSE;
 
   if (simple->need_update)
     goo_canvas_item_ensure_updated (item);
@@ -972,19 +973,19 @@
   /* Skip the item if the point isn't in the item's bounds. */
   if (simple->bounds.x1 > x || simple->bounds.x2 < x
       || simple->bounds.y1 > y || simple->bounds.y2 < y)
-    return NULL;
+    return found_items;
 
   /* Check if the item should receive events. */
   if (is_pointer_event)
     {
       if (simple_data->pointer_events == GOO_CANVAS_EVENTS_NONE)
-	return NULL;
+	return found_items;
       if (simple_data->pointer_events & GOO_CANVAS_EVENTS_VISIBLE_MASK
 	  && (!parent_visible
 	      || simple_data->visibility <= GOO_CANVAS_ITEM_INVISIBLE
 	      || (simple_data->visibility == GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD
 		  && simple->canvas->scale < simple_data->visibility_threshold)))
-	return NULL;
+	return found_items;
 
       pointer_events = simple_data->pointer_events;
     }
@@ -1008,14 +1009,14 @@
       if (!cairo_in_fill (cr, user_x, user_y))
 	{
 	  cairo_restore (cr);
-	  return NULL;
+	  return found_items;
 	}
     }
 
-  if (class->simple_get_item_at)
+  if (class->simple_is_item_at)
     {
-      found = class->simple_get_item_at (simple, user_x, user_y, cr,
-					 is_pointer_event);
+      add_item = class->simple_is_item_at (simple, user_x, user_y, cr,
+					   is_pointer_event);
     }
   else
     {
@@ -1024,12 +1025,15 @@
 
       if (goo_canvas_item_simple_check_in_path (simple, user_x, user_y, cr,
 						pointer_events))
-	found = item;
+	add_item = TRUE;
     }
 
   cairo_restore (cr);
 
-  return found;
+  if (add_item)
+    return g_list_prepend (found_items, item);
+  else
+    return found_items;
 }
 
 
@@ -1436,7 +1440,7 @@
   iface->get_parent	    = goo_canvas_item_simple_get_parent;
   iface->set_parent	    = goo_canvas_item_simple_set_parent;
   iface->get_bounds         = goo_canvas_item_simple_get_bounds;
-  iface->get_item_at	    = goo_canvas_item_simple_get_item_at;
+  iface->get_items_at	    = goo_canvas_item_simple_get_items_at;
   iface->update             = goo_canvas_item_simple_update;
   iface->get_requested_area = goo_canvas_item_simple_get_requested_area;
   iface->allocate_area      = goo_canvas_item_simple_allocate_area;

Index: goocanvasitemsimple.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasitemsimple.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- goocanvasitemsimple.h	17 Feb 2007 13:48:37 -0000	1.18
+++ goocanvasitemsimple.h	27 Feb 2007 01:01:39 -0000	1.19
@@ -102,13 +102,13 @@
  * @simple_update: subclasses should override this to calculate their new
  *  bounds, in user space.
  * @simple_paint: subclasses should override this to paint their item.
- * @simple_get_item_at: subclasses should override this to do hit-testing.
+ * @simple_is_item_at: subclasses should override this to do hit-testing.
  *
  * The #GooCanvasItemSimpleClass-struct struct contains several methods that
  * subclasses can override.
  *
  * Simple items need only implement the create_path() method. More complex
- * items must override the update(), paint() and get_item_at() methods.
+ * items must override the update(), paint() and is_item_at() methods.
  */
 struct _GooCanvasItemSimpleClass
 {
@@ -124,7 +124,7 @@
   void           (* simple_paint)	(GooCanvasItemSimple *simple,
 					 cairo_t             *cr,
 					 GooCanvasBounds     *bounds);
-  GooCanvasItem* (* simple_get_item_at) (GooCanvasItemSimple *simple,
+  gboolean       (* simple_is_item_at)  (GooCanvasItemSimple *simple,
 					 gdouble              x,
 					 gdouble              y,
 					 cairo_t             *cr,

Index: goocanvaspolyline.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvaspolyline.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- goocanvaspolyline.c	25 Feb 2007 17:37:57 -0000	1.13
+++ goocanvaspolyline.c	27 Feb 2007 01:01:39 -0000	1.14
@@ -763,39 +763,32 @@
 }
 
 
-static GooCanvasItem*
-goo_canvas_polyline_get_item_at (GooCanvasItemSimple *simple,
-				 gdouble              x,
-				 gdouble              y,
-				 cairo_t             *cr,
-				 gboolean             is_pointer_event)
+static gboolean
+goo_canvas_polyline_is_item_at (GooCanvasItemSimple *simple,
+				gdouble              x,
+				gdouble              y,
+				cairo_t             *cr,
+				gboolean             is_pointer_event)
 {
   GooCanvasItemSimpleData *simple_data = simple->simple_data;
   GooCanvasPolyline *polyline = (GooCanvasPolyline*) simple;
   GooCanvasPolylineData *polyline_data = polyline->polyline_data;
-  GooCanvasItem *found_item = NULL;
   GooCanvasPointerEvents pointer_events = GOO_CANVAS_EVENTS_ALL;
   gboolean do_stroke;
-  cairo_matrix_t matrix;
 
   if (polyline_data->num_points == 0)
-    return NULL;
+    return FALSE;
 
   /* Check if the item should receive events. */
   if (is_pointer_event)
     pointer_events = simple_data->pointer_events;
 
-  /* Remove any current translation, to avoid the 16-bit cairo limit. */
-  cairo_get_matrix (cr, &matrix);
-  matrix.x0 = matrix.y0 = 0.0;
-  cairo_set_matrix (cr, &matrix);
-
   goo_canvas_polyline_create_path (polyline, cr);
   if (goo_canvas_item_simple_check_in_path (simple, x, y, cr, pointer_events))
-    found_item = (GooCanvasItem*) simple;
+    return TRUE;
 
   /* Check the arrows, if the polyline has them. */
-  if (!found_item && (polyline_data->start_arrow || polyline_data->end_arrow)
+  if ((polyline_data->start_arrow || polyline_data->end_arrow)
       && polyline_data->num_points >= 2
       && (pointer_events & GOO_CANVAS_EVENTS_STROKE_MASK))
     {
@@ -807,19 +800,19 @@
 	    {
 	      goo_canvas_polyline_create_start_arrow_path (polyline, cr);
 	      if (cairo_in_fill (cr, x, y))
-		found_item = (GooCanvasItem*) simple;
+		return TRUE;
 	    }
 
-	  if (!found_item && polyline_data->end_arrow)
+	  if (polyline_data->end_arrow)
 	    {
 	      goo_canvas_polyline_create_end_arrow_path (polyline, cr);
 	      if (cairo_in_fill (cr, x, y))
-		found_item = (GooCanvasItem*) simple;
+		return TRUE;
 	    }
 	}
     }
 
-  return found_item;
+  return FALSE;
 }
 
 
@@ -973,7 +966,7 @@
 
   simple_class->simple_update        = goo_canvas_polyline_update;
   simple_class->simple_paint         = goo_canvas_polyline_paint;
-  simple_class->simple_get_item_at   = goo_canvas_polyline_get_item_at;
+  simple_class->simple_is_item_at    = goo_canvas_polyline_is_item_at;
 
   goo_canvas_polyline_install_common_properties (gobject_class);
 }

Index: goocanvastable.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvastable.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- goocanvastable.c	25 Feb 2007 17:37:57 -0000	1.9
+++ goocanvastable.c	27 Feb 2007 01:01:39 -0000	1.10
@@ -1832,13 +1832,14 @@
 }
 
 
-static GooCanvasItem*
-goo_canvas_table_get_item_at (GooCanvasItem  *item,
-			      gdouble         x,
-			      gdouble         y,
-			      cairo_t        *cr,
-			      gboolean        is_pointer_event,
-			      gboolean        parent_visible)
+static GList*
+goo_canvas_table_get_items_at (GooCanvasItem  *item,
+			       gdouble         x,
+			       gdouble         y,
+			       cairo_t        *cr,
+			       gboolean        is_pointer_event,
+			       gboolean        parent_visible,
+			       GList          *found_items)
 {
   GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
   GooCanvasItemSimpleData *simple_data = simple->simple_data;
@@ -1851,7 +1852,6 @@
   GArray *children = table_data->children;
   GooCanvasTableChild *table_child;
   GooCanvasItem *child;
-  GooCanvasItem *found_item = NULL;
   gboolean visible = parent_visible, check_clip = FALSE;
   double user_x = x, user_y = y;
   gint start_column, end_column, start_row, end_row, i;
@@ -1863,7 +1863,7 @@
   /* Skip the item if the point isn't in the item's bounds. */
   if (simple->bounds.x1 > x || simple->bounds.x2 < x
       || simple->bounds.y1 > y || simple->bounds.y2 < y)
-    return NULL;
+    return found_items;
 
   if (simple_data->visibility <= GOO_CANVAS_ITEM_INVISIBLE
       || (simple_data->visibility == GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD
@@ -1875,10 +1875,8 @@
       && (simple_data->pointer_events == GOO_CANVAS_EVENTS_NONE
 	  || ((simple_data->pointer_events & GOO_CANVAS_EVENTS_VISIBLE_MASK)
 	      && !visible)))
-    return NULL;
+    return found_items;
 
-  /* Step down from the top item to the bottom in the stack/layer, and return
-     the first item found that contains the given point. */
   cairo_save (cr);
   if (simple_data->transform)
     cairo_transform (cr, simple_data->transform);
@@ -1893,7 +1891,7 @@
       if (!cairo_in_fill (cr, user_x, user_y))
 	{
 	  cairo_restore (cr);
-	  return NULL;
+	  return found_items;
 	}
     }
 
@@ -1903,7 +1901,9 @@
       || layout_data->allocated_size[VERT] < layout_data->natural_size[VERT])
     check_clip = TRUE;
 
-  for (i = group->items->len - 1; i >= 0; i--)
+  /* Step up from the bottom of the children to the top, adding any items
+     found to the start of the list. */
+  for (i = 0; i < group->items->len; i++)
     {
       child = group->items->pdata[i];
 
@@ -1932,17 +1932,16 @@
       cairo_translate (cr, table_child->position[HORZ],
 		       table_child->position[VERT]);
 
-      found_item = goo_canvas_item_get_item_at (child, x, y, cr,
-						is_pointer_event, visible);
-      if (found_item)
-	break;
+      found_items = goo_canvas_item_get_items_at (child, x, y, cr,
+						  is_pointer_event, visible,
+						  found_items);
 
       cairo_translate (cr, -table_child->position[HORZ],
 		       -table_child->position[VERT]);
     }
   cairo_restore (cr);
 
-  return found_item;
+  return found_items;
 }
 
 
@@ -2000,7 +1999,7 @@
   iface->get_requested_area      = goo_canvas_table_get_requested_area;
   iface->allocate_area           = goo_canvas_table_allocate_area;
   iface->paint                   = goo_canvas_table_paint;
-  iface->get_item_at	         = goo_canvas_table_get_item_at;
+  iface->get_items_at	         = goo_canvas_table_get_items_at;
 
   iface->set_model               = goo_canvas_table_set_model;
 }

Index: goocanvastext.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvastext.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- goocanvastext.c	25 Feb 2007 18:25:52 -0000	1.15
+++ goocanvastext.c	27 Feb 2007 01:01:39 -0000	1.16
@@ -522,16 +522,15 @@
 }
 
 
-static GooCanvasItem*
-goo_canvas_text_get_item_at (GooCanvasItemSimple *simple,
-			     gdouble              x,
-			     gdouble              y,
-			     cairo_t             *cr,
-			     gboolean             is_pointer_event)
+static gboolean
+goo_canvas_text_is_item_at (GooCanvasItemSimple *simple,
+			    gdouble              x,
+			    gdouble              y,
+			    cairo_t             *cr,
+			    gboolean             is_pointer_event)
 {
   GooCanvasItemSimpleData *simple_data = simple->simple_data;
   GooCanvasText *text = (GooCanvasText*) simple;
-  GooCanvasItem *found_item = NULL;
   PangoLayout *layout;
   GooCanvasBounds bounds;
   PangoLayoutIter *iter;
@@ -539,15 +538,16 @@
   int px, py, x1, y1, x2, y2;
   int log_x2, ink_x2, log_y2, ink_y2;
   gdouble origin_x, origin_y;
+  gboolean in_item = FALSE;
 
   /* If there is no text just return. */
   if (!text->text_data->text || !text->text_data->text[0])
-    return NULL;
+    return FALSE;
 
   if (is_pointer_event
       && simple_data->pointer_events & GOO_CANVAS_EVENTS_PAINTED_MASK
       && goo_canvas_text_is_unpainted (simple_data->style))
-    return NULL;
+    return FALSE;
 
   layout = goo_canvas_text_create_layout (text, cr, &bounds,
 					  &origin_x, &origin_y);
@@ -580,7 +580,7 @@
 
       if (px >= x1 && px < x2 && py >= y1 && py < y2)
 	{
-	  found_item = (GooCanvasItem*) simple;
+	  in_item = TRUE;
 	  break;
 	}
 
@@ -590,7 +590,7 @@
 
   g_object_unref (layout);
 
-  return found_item;
+  return in_item;
 }
 
 
@@ -659,7 +659,7 @@
 
   simple_class->simple_update        = goo_canvas_text_update;
   simple_class->simple_paint         = goo_canvas_text_paint;
-  simple_class->simple_get_item_at   = goo_canvas_text_get_item_at;
+  simple_class->simple_is_item_at    = goo_canvas_text_is_item_at;
 
   goo_canvas_text_install_common_properties (gobject_class);
 }

Index: goocanvaswidget.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvaswidget.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- goocanvaswidget.c	25 Feb 2007 17:37:57 -0000	1.6
+++ goocanvaswidget.c	27 Feb 2007 01:01:39 -0000	1.7
@@ -449,17 +449,17 @@
 }
 
 
-static GooCanvasItem*
-goo_canvas_widget_get_item_at (GooCanvasItemSimple *simple,
-			       gdouble              x,
-			       gdouble              y,
-			       cairo_t             *cr,
-			       gboolean             is_pointer_event)
+static gboolean
+goo_canvas_widget_is_item_at (GooCanvasItemSimple *simple,
+			      gdouble              x,
+			      gdouble              y,
+			      cairo_t             *cr,
+			      gboolean             is_pointer_event)
 {
   /* For now we just assume that the widget covers its entire bounds so we just
-     return it. In future if widget items support transforms we'll need to
+     return TRUE. In future if widget items support transforms we'll need to
      modify this. */
-  return (GooCanvasItem*) simple;
+  return TRUE;
 }
 
 
@@ -485,7 +485,7 @@
 
   simple_class->simple_update        = goo_canvas_widget_update;
   simple_class->simple_paint         = goo_canvas_widget_paint;
-  simple_class->simple_get_item_at   = goo_canvas_widget_get_item_at;
+  simple_class->simple_is_item_at    = goo_canvas_widget_is_item_at;
 
   /* Register our accessible factory, but only if accessibility is enabled. */
   if (!ATK_IS_NO_OP_OBJECT_FACTORY (atk_registry_get_factory (atk_get_default_registry (), GTK_TYPE_WIDGET)))



More information about the cairo-commit mailing list