[goocanvas/new-api: 4/7] added support for a "line-width-tolerance" property.



commit a22da90fbb2f76e59181740d61e90f4e53559ee7
Author: Damon Chaplin <damon gnome org>
Date:   Thu Jun 24 15:03:37 2010 +0100

    added support for a "line-width-tolerance" property.

 demo/demo-large-line.c    |    2 +-
 demo/demo-large-rect.c    |    2 +-
 demo/demo.c               |    3 ++
 src/goocanvasgrid.c       |    6 ++--
 src/goocanvasitemsimple.c |   68 +++++++++++++++++++++++++++++++-------------
 src/goocanvasitemsimple.h |   23 ++++++++------
 src/goocanvaspath.c       |    2 +-
 src/goocanvaspolyline.c   |   12 ++++----
 src/goocanvasstyle.c      |   20 ++++++++++++-
 src/goocanvasstyle.h      |    1 +
 src/goocanvastable.c      |    2 +-
 11 files changed, 96 insertions(+), 45 deletions(-)
---
diff --git a/demo/demo-large-line.c b/demo/demo-large-line.c
index 8b1e9b3..c5b83b3 100644
--- a/demo/demo-large-line.c
+++ b/demo/demo-large-line.c
@@ -210,7 +210,7 @@ goo_demo_large_line_paint (GooCanvasItemSimple   *simple,
   GooDemoLargeLine *item = (GooDemoLargeLine*) simple;
   gdouble line_width;
 
-  goo_canvas_item_simple_set_stroke_options (simple, cr);
+  goo_canvas_item_simple_set_stroke_options (simple, cr, FALSE);
   line_width = goo_canvas_item_simple_get_line_width (simple);
   paint_large_line (item, cr, bounds, line_width,
 		    item->x1, item->y1, item->x2, item->y2);
diff --git a/demo/demo-large-rect.c b/demo/demo-large-rect.c
index 8caea3a..2a3ce19 100644
--- a/demo/demo-large-rect.c
+++ b/demo/demo-large-rect.c
@@ -160,7 +160,7 @@ goo_demo_large_rect_paint (GooCanvasItemSimple   *simple,
   line_width = goo_canvas_item_simple_get_line_width (simple);
   create_large_rect_path (item, cr, bounds, line_width,
 			  item->x, item->y, item->width, item->height);
-  goo_canvas_item_simple_paint_path (simple, cr);
+  goo_canvas_item_simple_paint_path (simple, cr, FALSE);
 }
 
 
diff --git a/demo/demo.c b/demo/demo.c
index 8977309..208c043 100644
--- a/demo/demo.c
+++ b/demo/demo.c
@@ -1053,6 +1053,7 @@ setup_lines (GooCanvasItem *root)
 				       390.0, 170.0,
 				       "stroke-color", "midnightblue",
 				       "line-width", 3.0,
+				       "line-width-tolerance", 4.0,
 				       "start-arrow", TRUE,
 				       "end-arrow", TRUE,
 				       "arrow-tip-length", 3.0,
@@ -1066,6 +1067,7 @@ setup_lines (GooCanvasItem *root)
 				       374.0, 220.0,
 				       "stroke-color", "blue",
 				       "line-width", 1.0,
+				       "line-width-tolerance", 4.0,
 				       "start-arrow", TRUE,
 				       "end-arrow", TRUE,
 				       "arrow-tip-length", 5.0,
@@ -1079,6 +1081,7 @@ setup_lines (GooCanvasItem *root)
 				       374.0, 180.0,
 				       "stroke-color", "blue",
 				       "line-width", 1.0,
+				       "line-width-tolerance", 4.0,
 				       "start-arrow", TRUE,
 				       "end-arrow", TRUE,
 				       "arrow-tip-length", 5.0,
diff --git a/src/goocanvasgrid.c b/src/goocanvasgrid.c
index 54b9542..9a02695 100644
--- a/src/goocanvasgrid.c
+++ b/src/goocanvasgrid.c
@@ -452,7 +452,7 @@ paint_vertical_lines (GooCanvasItemSimple   *simple,
   max_x = grid->x + grid->width;
   max_y = grid->y + grid->height;
 
-  has_stroke = goo_canvas_item_simple_set_stroke_options (simple, cr);
+  has_stroke = goo_canvas_item_simple_set_stroke_options (simple, cr, FALSE);
   line_width = goo_canvas_item_simple_get_line_width (simple);
 
   /* If the grid's vertical grid line pattern/color has been set, use that.
@@ -512,7 +512,7 @@ paint_horizontal_lines (GooCanvasItemSimple   *simple,
   max_x = grid->x + grid->width;
   max_y = grid->y + grid->height;
 
-  has_stroke = goo_canvas_item_simple_set_stroke_options (simple, cr);
+  has_stroke = goo_canvas_item_simple_set_stroke_options (simple, cr, FALSE);
   line_width = goo_canvas_item_simple_get_line_width (simple);
 
   /* If the grid's horizontal grid line pattern/color has been set, use that.
@@ -605,7 +605,7 @@ goo_canvas_grid_paint (GooCanvasItemSimple   *simple,
       if (grid->border_pattern)
 	cairo_set_source (cr, grid->border_pattern);
       else
-	goo_canvas_item_simple_set_stroke_options (simple, cr);
+	goo_canvas_item_simple_set_stroke_options (simple, cr, FALSE);
 
       cairo_set_line_width (cr, grid->border_width);
       half_border_width = grid->border_width / 2.0;
diff --git a/src/goocanvasitemsimple.c b/src/goocanvasitemsimple.c
index 0be1c6f..a5a43a1 100644
--- a/src/goocanvasitemsimple.c
+++ b/src/goocanvasitemsimple.c
@@ -50,6 +50,7 @@ enum {
 
   /* Line style & width properties. */
   PROP_LINE_WIDTH,
+  PROP_LINE_WIDTH_TOLERANCE,
   PROP_LINE_CAP,
   PROP_LINE_JOIN,
   PROP_LINE_JOIN_MITER_LIMIT,
@@ -137,7 +138,6 @@ goo_canvas_item_simple_get_property (GObject              *object,
   GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
   GooCanvasStyle *style = simple->style;
   AtkObject *accessible;
-  gdouble line_width = 2.0;
   gchar *font = NULL;
 
   switch (prop_id)
@@ -173,11 +173,10 @@ goo_canvas_item_simple_get_property (GObject              *object,
 
       /* Line style & width properties. */
     case PROP_LINE_WIDTH:
-      if (style)
-	line_width = style->line_width;
-      else if (simple->canvas)
-	line_width = goo_canvas_get_default_line_width (simple->canvas);
-      g_value_set_double (value, line_width);
+      g_value_set_double (value, style ? style->line_width : -1);
+      break;
+    case PROP_LINE_WIDTH_TOLERANCE:
+      g_value_set_double (value, style ? style->line_width_tolerance : 0);
       break;
     case PROP_LINE_CAP:
       g_value_set_enum (value, style ? style->line_cap : CAIRO_LINE_CAP_BUTT);
@@ -310,6 +309,10 @@ goo_canvas_item_simple_set_property (GObject              *object,
       style->line_width = g_value_get_double (value);
       recompute_bounds = TRUE;
       break;
+    case PROP_LINE_WIDTH_TOLERANCE:
+      style->line_width_tolerance = g_value_get_double (value);
+      need_update = FALSE;
+      break;
     case PROP_LINE_CAP:
       style->line_cap = g_value_get_enum (value);
       recompute_bounds = TRUE;
@@ -642,7 +645,7 @@ goo_canvas_item_simple_default_is_item_at (GooCanvasItemSimple *simple,
   /* Use the virtual method subclasses define to create the path. */
   class->simple_create_path (simple, cr);
 
-  if (goo_canvas_item_simple_check_in_path (simple, x, y, cr, pointer_events))
+  if (goo_canvas_item_simple_check_in_path (simple, x, y, cr, pointer_events, TRUE))
     return TRUE;
 
   return FALSE;
@@ -741,7 +744,7 @@ goo_canvas_item_simple_default_update (GooCanvasItemSimple   *simple,
   cairo_identity_matrix (cr);
 
   class->simple_create_path (simple, cr);
-  goo_canvas_item_simple_get_path_bounds (simple, cr, &simple->bounds);
+  goo_canvas_item_simple_get_path_bounds (simple, cr, &simple->bounds, TRUE);
 }
 
 
@@ -931,7 +934,7 @@ goo_canvas_item_simple_default_paint (GooCanvasItemSimple   *simple,
   GooCanvasItemSimpleClass *class = GOO_CANVAS_ITEM_SIMPLE_GET_CLASS (simple);
 
   class->simple_create_path (simple, cr);
-  goo_canvas_item_simple_paint_path (simple, cr);
+  goo_canvas_item_simple_paint_path (simple, cr, FALSE);
 }
 
 
@@ -973,12 +976,13 @@ goo_canvas_item_simple_query_tooltip (GooCanvasItem  *item,
  **/
 void
 goo_canvas_item_simple_paint_path (GooCanvasItemSimple *simple,
-				   cairo_t             *cr)
+				   cairo_t             *cr,
+				   gboolean             add_tolerance)
 {
   if (goo_canvas_item_simple_set_fill_options (simple, cr))
     cairo_fill_preserve (cr);
 
-  if (goo_canvas_item_simple_set_stroke_options (simple, cr))
+  if (goo_canvas_item_simple_set_stroke_options (simple, cr, add_tolerance))
     cairo_stroke (cr);
 
   cairo_new_path (cr);
@@ -1009,7 +1013,8 @@ goo_canvas_item_simple_paint_path (GooCanvasItemSimple *simple,
 void
 goo_canvas_item_simple_get_path_bounds (GooCanvasItemSimple *simple,
 					cairo_t             *cr,
-					GooCanvasBounds     *bounds)
+					GooCanvasBounds     *bounds,
+					gboolean             add_tolerance)
 {
   GooCanvasBounds fill_bounds, stroke_bounds;
 
@@ -1019,7 +1024,7 @@ goo_canvas_item_simple_get_path_bounds (GooCanvasItemSimple *simple,
 		      &fill_bounds.x2, &fill_bounds.y2);
 
   /* Check the stroke. */
-  goo_canvas_item_simple_set_stroke_options (simple, cr);
+  goo_canvas_item_simple_set_stroke_options (simple, cr, add_tolerance);
   cairo_stroke_extents (cr, &stroke_bounds.x1, &stroke_bounds.y1,
 			&stroke_bounds.x2, &stroke_bounds.y2);
 
@@ -1199,7 +1204,8 @@ goo_canvas_item_simple_check_in_path (GooCanvasItemSimple   *simple,
 				      gdouble                x,
 				      gdouble                y,
 				      cairo_t               *cr,
-				      GooCanvasPointerEvents pointer_events)
+				      GooCanvasPointerEvents pointer_events,
+				      gboolean               add_tolerance)
 {
   gboolean do_fill, do_stroke;
 
@@ -1217,7 +1223,7 @@ goo_canvas_item_simple_check_in_path (GooCanvasItemSimple   *simple,
   /* Check the stroke, if required. */
   if (pointer_events & GOO_CANVAS_EVENTS_STROKE_MASK)
     {
-      do_stroke = goo_canvas_item_simple_set_stroke_options (simple, cr);
+      do_stroke = goo_canvas_item_simple_set_stroke_options (simple, cr, add_tolerance);
       if (!(pointer_events & GOO_CANVAS_EVENTS_PAINTED_MASK) || do_stroke)
 	{
 	  if (cairo_in_stroke (cr, x, y))
@@ -1266,9 +1272,11 @@ goo_canvas_item_simple_set_style (GooCanvasItemSimple   *simple,
 
 gboolean
 goo_canvas_item_simple_set_stroke_options (GooCanvasItemSimple   *simple,
-					   cairo_t               *cr)
+					   cairo_t               *cr,
+					   gboolean		  add_tolerance)
 {
   GooCanvasStyle *style = simple->style;
+  gdouble line_width;
 
   /* If no style is set, just reset the source to black and return TRUE so the
      default style will be used. */
@@ -1289,8 +1297,20 @@ goo_canvas_item_simple_set_stroke_options (GooCanvasItemSimple   *simple,
   if (style->antialias != CAIRO_ANTIALIAS_GRAY)
     cairo_set_antialias (cr, style->antialias);
 
-  if (style->line_width >= 0.0)
-    cairo_set_line_width (cr, style->line_width);
+  if (add_tolerance && style->line_width_tolerance > 0)
+    {
+      if (style->line_width >= 0.0)
+	line_width = style->line_width;
+      else
+	line_width = cairo_get_line_width (cr);
+
+      cairo_set_line_width (cr, line_width + style->line_width_tolerance);
+    }
+  else
+    {
+      if (style->line_width >= 0.0)
+	cairo_set_line_width (cr, style->line_width);
+    }
 
   if (style->line_cap != CAIRO_LINE_CAP_BUTT)
     cairo_set_line_cap (cr, style->line_cap);
@@ -1429,8 +1449,16 @@ goo_canvas_item_simple_class_init (GooCanvasItemSimpleClass *klass)
   g_object_class_install_property (gobject_class, PROP_LINE_WIDTH,
 				   g_param_spec_double ("line-width",
 							_("Line Width"),
-							_("The line width to use for the item's perimeter"),
-							0.0, G_MAXDOUBLE, 2.0,
+							_("The line width to use for the item's perimeter, or -1 to use the default line width"),
+							-G_MAXDOUBLE,
+							G_MAXDOUBLE, -1.0,
+							G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_LINE_WIDTH_TOLERANCE,
+				   g_param_spec_double ("line-width-tolerance",
+							_("Line Width Tolerance"),
+							_("The tolerance added to the line width when testing for mouse events"),
+							0.0, G_MAXDOUBLE, 0.0,
 							G_PARAM_READWRITE));
 
   g_object_class_install_property (gobject_class, PROP_LINE_CAP,
diff --git a/src/goocanvasitemsimple.h b/src/goocanvasitemsimple.h
index 52fc324..9fd7380 100644
--- a/src/goocanvasitemsimple.h
+++ b/src/goocanvasitemsimple.h
@@ -34,8 +34,7 @@ typedef struct _GooCanvasItemSimpleClass  GooCanvasItemSimpleClass;
  * @bounds: the bounds of the item, in device space.
  * @need_update: if the item needs to recompute its bounds and redraw.
  * @need_entire_subtree_update: if all descendants need to be updated.
- * @pen: the pen to draw the strokes with.
- * @brush: the brush to fill the items with.
+ * @style: the style to draw the item with.
  * @transform: the transformation matrix of the item, or %NULL.
  * @clip_path_commands: an array of #GooCanvasPathCommand specifying the clip
  *  path of the item, or %NULL.
@@ -137,7 +136,8 @@ void     goo_canvas_item_simple_set_style		(GooCanvasItemSimple   *simple,
 
 void     goo_canvas_item_simple_get_path_bounds		(GooCanvasItemSimple	*item,
 							 cairo_t		*cr,
-							 GooCanvasBounds	*bounds);
+							 GooCanvasBounds	*bounds,
+							 gboolean                add_tolerance);
 void     goo_canvas_item_simple_user_bounds_to_device	(GooCanvasItemSimple	*item,
 							 cairo_t		*cr,
 							 GooCanvasBounds	*bounds);
@@ -148,18 +148,21 @@ gboolean goo_canvas_item_simple_check_in_path		(GooCanvasItemSimple	*item,
 							 gdouble		 x,
 							 gdouble		 y,
 							 cairo_t		*cr,
-							 GooCanvasPointerEvents  pointer_events);
+							 GooCanvasPointerEvents  pointer_events,
+							 gboolean                add_tolerance);
 void     goo_canvas_item_simple_paint_path		(GooCanvasItemSimple	*item,
-							 cairo_t		*cr);
+							 cairo_t		*cr,
+							 gboolean		 add_tolerance);
 
 void     goo_canvas_item_simple_changed			(GooCanvasItemSimple	*item,
 							 gboolean		 recompute_bounds);
-gdouble  goo_canvas_item_simple_get_line_width		(GooCanvasItemSimple   *item);
+gdouble  goo_canvas_item_simple_get_line_width		(GooCanvasItemSimple    *item);
 
-gboolean goo_canvas_item_simple_set_stroke_options	(GooCanvasItemSimple   *simple,
-							 cairo_t               *cr);
-gboolean goo_canvas_item_simple_set_fill_options	(GooCanvasItemSimple   *simple,
-							 cairo_t               *cr);
+gboolean goo_canvas_item_simple_set_stroke_options	(GooCanvasItemSimple    *simple,
+							 cairo_t                *cr,
+							 gboolean		 add_tolerance);
+gboolean goo_canvas_item_simple_set_fill_options	(GooCanvasItemSimple    *simple,
+							 cairo_t                *cr);
 
 
 G_END_DECLS
diff --git a/src/goocanvaspath.c b/src/goocanvaspath.c
index ff1a5d5..71c8fb5 100644
--- a/src/goocanvaspath.c
+++ b/src/goocanvaspath.c
@@ -456,7 +456,7 @@ goo_canvas_path_is_item_at (GooCanvasItemSimple *simple,
     pointer_events = simple->pointer_events;
 
   goo_canvas_path_create_path (simple, cr);
-  if (goo_canvas_item_simple_check_in_path (simple, x, y, cr, pointer_events))
+  if (goo_canvas_item_simple_check_in_path (simple, x, y, cr, pointer_events, TRUE))
     return TRUE;
 
   return FALSE;
diff --git a/src/goocanvaspolyline.c b/src/goocanvaspolyline.c
index 08ba072..cbea020 100644
--- a/src/goocanvaspolyline.c
+++ b/src/goocanvaspolyline.c
@@ -768,7 +768,7 @@ goo_canvas_polyline_is_item_at (GooCanvasItemSimple *simple,
     pointer_events &= ~GOO_CANVAS_EVENTS_FILL_MASK;
 
   goo_canvas_polyline_create_path (polyline, cr);
-  if (goo_canvas_item_simple_check_in_path (simple, x, y, cr, pointer_events))
+  if (goo_canvas_item_simple_check_in_path (simple, x, y, cr, pointer_events, TRUE))
     return TRUE;
 
   /* Check the arrows, if the polyline has them. */
@@ -777,7 +777,7 @@ goo_canvas_polyline_is_item_at (GooCanvasItemSimple *simple,
       && (pointer_events & GOO_CANVAS_EVENTS_STROKE_MASK))
     {
       /* We use the stroke pattern to match the style of the line. */
-      do_stroke = goo_canvas_item_simple_set_stroke_options (simple, cr);
+      do_stroke = goo_canvas_item_simple_set_stroke_options (simple, cr, TRUE);
       if (!(pointer_events & GOO_CANVAS_EVENTS_PAINTED_MASK) || do_stroke)
 	{
 	  if (polyline->start_arrow)
@@ -820,14 +820,14 @@ goo_canvas_polyline_compute_bounds (GooCanvasPolyline     *polyline,
   cairo_identity_matrix (cr);
 
   goo_canvas_polyline_create_path (polyline, cr);
-  goo_canvas_item_simple_get_path_bounds (simple, cr, bounds);
+  goo_canvas_item_simple_get_path_bounds (simple, cr, bounds, TRUE);
 
   /* Add on the arrows, if required. */
   if ((polyline->start_arrow || polyline->end_arrow)
       && polyline->num_points >= 2)
     {
       /* We use the stroke pattern to match the style of the line. */
-      goo_canvas_item_simple_set_stroke_options (simple, cr);
+      goo_canvas_item_simple_set_stroke_options (simple, cr, TRUE);
 
       if (polyline->start_arrow)
 	{
@@ -880,14 +880,14 @@ goo_canvas_polyline_paint (GooCanvasItemSimple   *simple,
     return;
 
   goo_canvas_polyline_create_path (polyline, cr);
-  goo_canvas_item_simple_paint_path (simple, cr);
+  goo_canvas_item_simple_paint_path (simple, cr, FALSE);
 
   /* Paint the arrows, if required. */
   if ((polyline->start_arrow || polyline->end_arrow)
       && polyline->num_points >= 2)
     {
       /* We use the stroke pattern to match the style of the line. */
-      goo_canvas_item_simple_set_stroke_options (simple, cr);
+      goo_canvas_item_simple_set_stroke_options (simple, cr, FALSE);
 
       if (polyline->start_arrow)
 	{
diff --git a/src/goocanvasstyle.c b/src/goocanvasstyle.c
index 4d6f01e..422a012 100644
--- a/src/goocanvasstyle.c
+++ b/src/goocanvasstyle.c
@@ -26,6 +26,7 @@ enum {
 
   /* Line style & width properties. */
   PROP_LINE_WIDTH,
+  PROP_LINE_WIDTH_TOLERANCE,
   PROP_LINE_CAP,
   PROP_LINE_JOIN,
   PROP_LINE_JOIN_MITER_LIMIT,
@@ -56,6 +57,7 @@ goo_canvas_style_init (GooCanvasStyle *style)
   style->font_desc = NULL;
 
   style->line_width = -1.0;
+  style->line_width_tolerance = -1.0;
   style->line_join_miter_limit = 10.0;
 
   style->stroke_pattern_set = FALSE;
@@ -132,6 +134,9 @@ goo_canvas_style_get_property (GObject              *object,
     case PROP_LINE_WIDTH:
       g_value_set_double (value, style->line_width);
       break;
+    case PROP_LINE_WIDTH_TOLERANCE:
+      g_value_set_double (value, style->line_width_tolerance);
+      break;
     case PROP_LINE_CAP:
       g_value_set_enum (value, style->line_cap);
       break;
@@ -230,6 +235,9 @@ goo_canvas_style_set_property (GObject              *object,
     case PROP_LINE_WIDTH:
       style->line_width = g_value_get_double (value);
       break;
+    case PROP_LINE_WIDTH_TOLERANCE:
+      style->line_width_tolerance = g_value_get_double (value);
+      break;
     case PROP_LINE_CAP:
       style->line_cap = g_value_get_enum (value);
       break;
@@ -361,8 +369,16 @@ goo_canvas_style_class_init (GooCanvasStyleClass *klass)
   g_object_class_install_property (gobject_class, PROP_LINE_WIDTH,
 				   g_param_spec_double ("line-width",
 							_("Line Width"),
-							_("The line width to use for the item's perimeter"),
-							0.0, G_MAXDOUBLE, 2.0,
+							_("The line width to use for the item's perimeter, or -1 to use the default line width"),
+							-G_MAXDOUBLE,
+							G_MAXDOUBLE, -1.0,
+							G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_LINE_WIDTH_TOLERANCE,
+				   g_param_spec_double ("line-width-tolerance",
+							_("Line Width Tolerance"),
+							_("The tolerance added to the line width when testing for mouse events"),
+							0.0, G_MAXDOUBLE, 0.0,
 							G_PARAM_READWRITE));
 
   g_object_class_install_property (gobject_class, PROP_LINE_CAP,
diff --git a/src/goocanvasstyle.h b/src/goocanvasstyle.h
index 6b3c07d..3b6d79d 100644
--- a/src/goocanvasstyle.h
+++ b/src/goocanvasstyle.h
@@ -36,6 +36,7 @@ struct _GooCanvasStyle
   PangoFontDescription *font_desc;
 
   gdouble line_width;
+  gdouble line_width_tolerance;
   gdouble line_join_miter_limit;
 
   guint stroke_pattern_set	    : 1;
diff --git a/src/goocanvastable.c b/src/goocanvastable.c
index 421d23e..1199527 100644
--- a/src/goocanvastable.c
+++ b/src/goocanvastable.c
@@ -2160,7 +2160,7 @@ goo_canvas_table_paint (GooCanvasItem         *item,
 
   /* We use the style for the stroke color, but the line cap style and line
      width are overridden here. */
-  goo_canvas_item_simple_set_stroke_options (simple, cr);
+  goo_canvas_item_simple_set_stroke_options (simple, cr, FALSE);
 
   cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
 



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