nautilus-3.6.3/libnautilus-private/nautilus-selection-canvas-item.c

No issues found

  1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
  2 
  3 /* Nautilus - Canvas item for floating selection.
  4  *
  5  * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
  6  * Copyright (C) 2011 Red Hat Inc.
  7  *
  8  * This library is free software; you can redistribute it and/or
  9  * modify it under the terms of the GNU Library General Public
 10  * License as published by the Free Software Foundation; either
 11  * version 2 of the License, or (at your option) any later version.
 12  *
 13  * This library is distributed in the hope that it will be useful,
 14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16  * Library General Public License for more details.
 17  *
 18  * You should have received a copy of the GNU Library General Public
 19  * License along with this library; if not, write to the
 20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 21  * Boston, MA 02111-1307, USA.
 22  *
 23  * Authors: Federico Mena <federico@nuclecu.unam.mx>
 24  *          Cosimo Cecchi <cosimoc@redhat.com>
 25  */
 26 
 27 #include <config.h>
 28 
 29 #include "nautilus-selection-canvas-item.h"
 30 
 31 #include <math.h>
 32 
 33 enum {
 34 	PROP_X1 = 1,
 35 	PROP_Y1,
 36 	PROP_X2,
 37 	PROP_Y2,
 38 	PROP_FILL_COLOR_RGBA,
 39 	PROP_OUTLINE_COLOR_RGBA,
 40 	PROP_OUTLINE_STIPPLING,
 41 	PROP_WIDTH_PIXELS,
 42 	NUM_PROPERTIES
 43 };
 44 
 45 static GParamSpec *properties[NUM_PROPERTIES] = { NULL };
 46 
 47 typedef struct {
 48   /*< public >*/
 49   int x0, y0, x1, y1;
 50 }  Rect;
 51 
 52 struct _NautilusSelectionCanvasItemDetails {
 53 	Rect last_update_rect;
 54 	Rect last_outline_update_rect;
 55 	int last_outline_update_width;
 56 
 57 	double x1, y1, x2, y2;		/* Corners of item */
 58 	double width;			/* Outline width */
 59 
 60         GdkRGBA fill_color;
 61         GdkRGBA outline_color;
 62 
 63 	gboolean outline_stippling;
 64 
 65 	/* Configuration flags */
 66 
 67 	unsigned int fill_set : 1;	/* Is fill color set? */
 68 	unsigned int outline_set : 1;	/* Is outline color set? */
 69 
 70 	double fade_out_fill_alpha;
 71 	double fade_out_outline_alpha;
 72 
 73 	double fade_out_fill_delta;
 74 	double fade_out_outline_delta;	
 75 
 76 	guint fade_out_handler_id;
 77 };
 78 
 79 G_DEFINE_TYPE (NautilusSelectionCanvasItem, nautilus_selection_canvas_item, EEL_TYPE_CANVAS_ITEM);
 80 
 81 #define DASH_ON 0.8
 82 #define DASH_OFF 1.7
 83 static void
 84 nautilus_selection_canvas_item_draw (EelCanvasItem *item,
 85 				     cairo_t *cr,
 86 				     cairo_region_t *region)
 87 {
 88 	NautilusSelectionCanvasItem *self;
 89 	double x1, y1, x2, y2;
 90 	int cx1, cy1, cx2, cy2;
 91 	double i2w_dx, i2w_dy;
 92 
 93 	self = NAUTILUS_SELECTION_CANVAS_ITEM (item);
 94 
 95 	/* Get canvas pixel coordinates */
 96 	i2w_dx = 0.0;
 97 	i2w_dy = 0.0;
 98 	eel_canvas_item_i2w (item, &i2w_dx, &i2w_dy);
 99 	
100 	x1 = self->priv->x1 + i2w_dx;
101 	y1 = self->priv->y1 + i2w_dy;
102 	x2 = self->priv->x2 + i2w_dx;
103 	y2 = self->priv->y2 + i2w_dy;
104 
105 	eel_canvas_w2c (item->canvas, x1, y1, &cx1, &cy1);
106 	eel_canvas_w2c (item->canvas, x2, y2, &cx2, &cy2);
107 	
108 	if (cx2 <= cx1 || cy2 <= cy1 ) {
109 		return;
110 	}
111 
112 	cairo_save (cr);
113 
114 	if (self->priv->fill_set) {
115 		GdkRGBA actual_fill;
116 
117 		actual_fill = self->priv->fill_color;
118 
119 		if (self->priv->fade_out_handler_id != 0) {
120 			actual_fill.alpha = self->priv->fade_out_fill_alpha;
121 		}
122 
123 		gdk_cairo_set_source_rgba (cr, &actual_fill);
124 		cairo_rectangle (cr,
125 				 cx1, cy1,
126 				 cx2 - cx1 + 1,
127 				 cy2 - cy1 + 1);
128 		cairo_fill (cr);
129 	}
130 
131 	if (self->priv->outline_set) {
132 		GdkRGBA actual_outline;
133 
134 		actual_outline = self->priv->outline_color;
135 
136 		if (self->priv->fade_out_handler_id != 0) {
137 			actual_outline.alpha = self->priv->fade_out_outline_alpha;
138 		}
139 
140 		gdk_cairo_set_source_rgba (cr, &actual_outline);
141 		cairo_set_line_width (cr, (int) self->priv->width);
142 
143 		if (self->priv->outline_stippling) {
144 			double dash[2] = { DASH_ON, DASH_OFF };
145 
146 			cairo_set_dash (cr, dash, G_N_ELEMENTS (dash), 0);
147 		}
148 
149 		cairo_rectangle (cr,
150 				 cx1 + 0.5, cy1 + 0.5,
151 				 cx2 - cx1,
152 				 cy2 - cy1);
153 		cairo_stroke (cr);
154 	}
155 
156 	cairo_restore (cr);
157 }
158 
159 static double
160 nautilus_selection_canvas_item_point (EelCanvasItem *item,
161 				      double x,
162 				      double y,
163 				      int cx,
164 				      int cy,
165 				      EelCanvasItem **actual_item)
166 {
167 	NautilusSelectionCanvasItem *self;
168 	double x1, y1, x2, y2;
169 	double hwidth;
170 	double dx, dy;
171 	double tmp;
172 
173 	self = NAUTILUS_SELECTION_CANVAS_ITEM (item);
174 	*actual_item = item;
175 
176 	/* Find the bounds for the rectangle plus its outline width */
177 
178 	x1 = self->priv->x1;
179 	y1 = self->priv->y1;
180 	x2 = self->priv->x2;
181 	y2 = self->priv->y2;
182 
183 	if (self->priv->outline_set) {
184 		hwidth = (self->priv->width / item->canvas->pixels_per_unit) / 2.0;
185 
186 		x1 -= hwidth;
187 		y1 -= hwidth;
188 		x2 += hwidth;
189 		y2 += hwidth;
190 	} else
191 		hwidth = 0.0;
192 
193 	/* Is point inside rectangle (which can be hollow if it has no fill set)? */
194 
195 	if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) {
196 		if (self->priv->fill_set || !self->priv->outline_set)
197 			return 0.0;
198 
199 		dx = x - x1;
200 		tmp = x2 - x;
201 		if (tmp < dx)
202 			dx = tmp;
203 
204 		dy = y - y1;
205 		tmp = y2 - y;
206 		if (tmp < dy)
207 			dy = tmp;
208 
209 		if (dy < dx)
210 			dx = dy;
211 
212 		dx -= 2.0 * hwidth;
213 
214 		if (dx < 0.0)
215 			return 0.0;
216 		else
217 			return dx;
218 	}
219 
220 	/* Point is outside rectangle */
221 
222 	if (x < x1)
223 		dx = x1 - x;
224 	else if (x > x2)
225 		dx = x - x2;
226 	else
227 		dx = 0.0;
228 
229 	if (y < y1)
230 		dy = y1 - y;
231 	else if (y > y2)
232 		dy = y - y2;
233 	else
234 		dy = 0.0;
235 
236 	return sqrt (dx * dx + dy * dy);
237 }
238 
239 static void
240 request_redraw_borders (EelCanvas *canvas,
241 			Rect      *update_rect,
242 			int        width)
243 {
244 	eel_canvas_request_redraw (canvas,
245 				   update_rect->x0, update_rect->y0,
246 				   update_rect->x1, update_rect->y0 + width);
247 	eel_canvas_request_redraw (canvas,
248 				   update_rect->x0, update_rect->y1-width,
249 				   update_rect->x1, update_rect->y1);
250 	eel_canvas_request_redraw (canvas,
251 				   update_rect->x0,       update_rect->y0,
252 				   update_rect->x0+width, update_rect->y1);
253 	eel_canvas_request_redraw (canvas,
254 				   update_rect->x1-width, update_rect->y0,
255 				   update_rect->x1,       update_rect->y1);
256 }
257 
258 static Rect make_rect (int x0, int y0, int x1, int y1);
259 
260 static int
261 rect_empty (const Rect *src) {
262   return (src->x1 <= src->x0 || src->y1 <= src->y0);
263 }
264 
265 static gboolean
266 rects_intersect (Rect r1, Rect r2)
267 {
268 	if (r1.x0 >= r2.x1) {
269 		return FALSE;
270 	}
271 	if (r2.x0 >= r1.x1) {
272 		return FALSE;
273 	}
274 	if (r1.y0 >= r2.y1) {
275 		return FALSE;
276 	}
277 	if (r2.y0 >= r1.y1) {
278 		return FALSE;
279 	}
280 	return TRUE;
281 }
282 
283 static void
284 diff_rects_guts (Rect ra, Rect rb, int *count, Rect result[4])
285 {
286 	if (ra.x0 < rb.x0) {
287 		result[(*count)++] = make_rect (ra.x0, ra.y0, rb.x0, ra.y1);
288 	}
289 	if (ra.y0 < rb.y0) {
290 		result[(*count)++] = make_rect (ra.x0, ra.y0, ra.x1, rb.y0);
291 	}
292 	if (ra.x1 < rb.x1) {
293 		result[(*count)++] = make_rect (ra.x1, rb.y0, rb.x1, rb.y1);
294 	}
295 	if (ra.y1 < rb.y1) {
296 		result[(*count)++] = make_rect (rb.x0, ra.y1, rb.x1, rb.y1);
297 	}
298 }
299 
300 static void
301 diff_rects (Rect r1, Rect r2, int *count, Rect result[4])
302 {
303 	g_assert (count != NULL);
304 	g_assert (result != NULL);
305 
306 	*count = 0;
307 
308 	if (rects_intersect (r1, r2)) {
309 		diff_rects_guts (r1, r2, count, result);
310 		diff_rects_guts (r2, r1, count, result);
311 	} else {
312 		if (!rect_empty (&r1)) {
313 			result[(*count)++] = r1;
314 		}
315 		if (!rect_empty (&r2)) {
316 			result[(*count)++] = r2;
317 		}
318 	}
319 }
320 
321 static Rect
322 make_rect (int x0, int y0, int x1, int y1)
323 {
324 	Rect r;
325 
326 	r.x0 = x0;
327 	r.y0 = y0;
328 	r.x1 = x1;
329 	r.y1 = y1;
330 	return r;
331 }
332 
333 static void
334 nautilus_selection_canvas_item_update (EelCanvasItem *item,
335 				       double i2w_dx,
336 				       double i2w_dy,
337 				       gint flags)
338 {
339 	NautilusSelectionCanvasItem *self;
340 	NautilusSelectionCanvasItemDetails *priv;
341 	double x1, y1, x2, y2;
342 	int cx1, cy1, cx2, cy2;
343 	int repaint_rects_count, i;
344 	int width_pixels;
345 	int width_lt, width_rb;
346 	Rect update_rect, repaint_rects[4];
347 
348 	if (EEL_CANVAS_ITEM_CLASS (nautilus_selection_canvas_item_parent_class)->update)
349 		(* EEL_CANVAS_ITEM_CLASS (nautilus_selection_canvas_item_parent_class)->update) (item, i2w_dx, i2w_dy, flags);
350 
351 	self = NAUTILUS_SELECTION_CANVAS_ITEM (item);
352 	priv = self->priv;
353 
354 	x1 = priv->x1 + i2w_dx;
355 	y1 = priv->y1 + i2w_dy;
356 	x2 = priv->x2 + i2w_dx;
357 	y2 = priv->y2 + i2w_dy;
358 
359 	eel_canvas_w2c (item->canvas, x1, y1, &cx1, &cy1);
360 	eel_canvas_w2c (item->canvas, x2, y2, &cx2, &cy2);
361 
362 	update_rect = make_rect (cx1, cy1, cx2+1, cy2+1);
363 	diff_rects (update_rect, priv->last_update_rect,
364 		    &repaint_rects_count, repaint_rects);
365 	for (i = 0; i < repaint_rects_count; i++) {
366 		eel_canvas_request_redraw (item->canvas,
367 					   repaint_rects[i].x0, repaint_rects[i].y0,
368 					   repaint_rects[i].x1, repaint_rects[i].y1);
369 	}
370 
371 	priv->last_update_rect = update_rect;
372 
373 	if (priv->outline_set) {
374 		/* Outline and bounding box */
375 		width_pixels = (int) priv->width;
376 		width_lt = width_pixels / 2;
377 		width_rb = (width_pixels + 1) / 2;
378 		
379 		cx1 -= width_lt;
380 		cy1 -= width_lt;
381 		cx2 += width_rb;
382 		cy2 += width_rb;
383 
384 		update_rect = make_rect (cx1, cy1, cx2, cy2);
385 		request_redraw_borders (item->canvas, &update_rect,
386 					(width_lt + width_rb));
387 		request_redraw_borders (item->canvas, &priv->last_outline_update_rect,
388 					priv->last_outline_update_width);
389 		priv->last_outline_update_rect = update_rect;
390 		priv->last_outline_update_width = width_lt + width_rb;
391 		
392 		item->x1 = cx1;
393 		item->y1 = cy1;
394 		item->x2 = cx2+1;
395 		item->y2 = cy2+1;
396 	} else {
397 		item->x1 = cx1;
398 		item->y1 = cy1;
399 		item->x2 = cx2+1;
400 		item->y2 = cy2+1;
401 	}
402 }
403 
404 static void
405 nautilus_selection_canvas_item_translate (EelCanvasItem *item,
406 					  double dx,
407 					  double dy)
408 {
409 	NautilusSelectionCanvasItem *self;
410 
411 	self = NAUTILUS_SELECTION_CANVAS_ITEM (item);
412 
413 	self->priv->x1 += dx;
414 	self->priv->y1 += dy;
415 	self->priv->x2 += dx;
416 	self->priv->y2 += dy;
417 }
418 
419 static void
420 nautilus_selection_canvas_item_bounds (EelCanvasItem *item,
421 				       double *x1,
422 				       double *y1,
423 				       double *x2,
424 				       double *y2)
425 {
426 	NautilusSelectionCanvasItem *self;
427 	double hwidth;
428 
429 	self = NAUTILUS_SELECTION_CANVAS_ITEM (item);
430 
431 	hwidth = (self->priv->width / item->canvas->pixels_per_unit) / 2.0;
432 
433 	*x1 = self->priv->x1 - hwidth;
434 	*y1 = self->priv->y1 - hwidth;
435 	*x2 = self->priv->x2 + hwidth;
436 	*y2 = self->priv->y2 + hwidth;
437 }
438 
439 #define FADE_OUT_STEPS 5
440 #define FADE_OUT_SPEED 30
441 
442 static gboolean
443 fade_and_request_redraw (gpointer user_data)
444 {
445 	NautilusSelectionCanvasItem *self = user_data;
446 
447 	if (self->priv->fade_out_fill_alpha <= 0 ||
448 	    self->priv->fade_out_outline_alpha <= 0) {
449 		self->priv->fade_out_handler_id = 0;
450 		eel_canvas_item_destroy (EEL_CANVAS_ITEM (self));
451 
452 		return FALSE;
453 	}
454 
455 	self->priv->fade_out_fill_alpha -= self->priv->fade_out_fill_delta;
456 	self->priv->fade_out_outline_alpha -= self->priv->fade_out_outline_delta;
457 
458 	eel_canvas_item_request_redraw (EEL_CANVAS_ITEM (self));
459 
460 	return TRUE;
461 }
462 
463 void
464 nautilus_selection_canvas_item_fade_out (NautilusSelectionCanvasItem *self,
465 					 guint transition_time)
466 {
467 	self->priv->fade_out_fill_alpha = self->priv->fill_color.alpha;
468 	self->priv->fade_out_outline_alpha = self->priv->outline_color.alpha;
469 
470 	self->priv->fade_out_fill_delta = self->priv->fade_out_fill_alpha / FADE_OUT_STEPS;
471 	self->priv->fade_out_outline_delta = self->priv->fade_out_outline_alpha / FADE_OUT_STEPS;
472 
473 	self->priv->fade_out_handler_id =
474 		g_timeout_add ((guint) (transition_time / FADE_OUT_STEPS),
475 			       fade_and_request_redraw, self);
476 }
477 
478 static void
479 nautilus_selection_canvas_item_dispose (GObject *obj)
480 {
481 	NautilusSelectionCanvasItem *self = NAUTILUS_SELECTION_CANVAS_ITEM (obj);
482 
483 	if (self->priv->fade_out_handler_id != 0) {
484 		g_source_remove (self->priv->fade_out_handler_id);
485 		self->priv->fade_out_handler_id = 0;
486 	}
487 
488 	G_OBJECT_CLASS (nautilus_selection_canvas_item_parent_class)->dispose (obj);
489 }
490 
491 static void
492 do_set_fill (NautilusSelectionCanvasItem *self,
493 	     gboolean fill_set)
494 {
495 	if (self->priv->fill_set != fill_set) {
496 		self->priv->fill_set = fill_set;
497 		eel_canvas_item_request_update (EEL_CANVAS_ITEM (self));
498 	}
499 }
500 
501 static void
502 do_set_outline (NautilusSelectionCanvasItem *self,
503 		gboolean outline_set)
504 {
505 	if (self->priv->outline_set != outline_set) {
506 		self->priv->outline_set = outline_set;
507 		eel_canvas_item_request_update (EEL_CANVAS_ITEM (self));
508 	}
509 }
510 
511 static void
512 nautilus_selection_canvas_item_set_property (GObject *object,
513 					     guint param_id,
514 					     const GValue *value,
515 					     GParamSpec *pspec)
516 {
517 	EelCanvasItem *item;
518 	NautilusSelectionCanvasItem *self;
519 
520 	self = NAUTILUS_SELECTION_CANVAS_ITEM (object);
521 	item = EEL_CANVAS_ITEM (object);
522 
523 	switch (param_id) {
524 	case PROP_X1:
525 		self->priv->x1 = g_value_get_double (value);
526 
527 		eel_canvas_item_request_update (item);
528 		break;
529 
530 	case PROP_Y1:
531 		self->priv->y1 = g_value_get_double (value);
532 
533 		eel_canvas_item_request_update (item);
534 		break;
535 
536 	case PROP_X2:
537 		self->priv->x2 = g_value_get_double (value);
538 
539 		eel_canvas_item_request_update (item);
540 		break;
541 
542 	case PROP_Y2:
543 		self->priv->y2 = g_value_get_double (value);
544 
545 		eel_canvas_item_request_update (item);
546 		break;
547 
548 	case PROP_FILL_COLOR_RGBA: {
549 		GdkRGBA *color;
550 
551 		color = g_value_get_boxed (value);
552 
553 		do_set_fill (self, color != NULL);
554 
555 		if (color != NULL) {
556 			self->priv->fill_color = *color;
557 		}
558 
559 		eel_canvas_item_request_redraw (item);		
560 		break;
561 	}
562 
563 	case PROP_OUTLINE_COLOR_RGBA: {
564 		GdkRGBA *color;
565 
566 		color = g_value_get_boxed (value);
567 
568 		do_set_outline (self, color != NULL);
569 
570 		if (color != NULL) {
571 			self->priv->outline_color = *color;
572 		}
573 
574 		eel_canvas_item_request_redraw (item);		
575 		break;
576 	}
577 
578 	case PROP_OUTLINE_STIPPLING:
579 		self->priv->outline_stippling = g_value_get_boolean (value);
580 
581 		eel_canvas_item_request_redraw (item);
582 		break;
583 
584 	case PROP_WIDTH_PIXELS:
585 		self->priv->width = g_value_get_uint (value);
586 
587 		eel_canvas_item_request_update (item);
588 		break;
589 
590 	default:
591 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
592 		break;
593 	}
594 }
595 
596 static void
597 nautilus_selection_canvas_item_get_property (GObject *object,
598 					     guint param_id,
599 					     GValue *value,
600 					     GParamSpec *pspec)
601 {
602 	NautilusSelectionCanvasItem *self;
603 
604 	self = NAUTILUS_SELECTION_CANVAS_ITEM (object);
605 
606 	switch (param_id) {
607 	case PROP_X1:
608 		g_value_set_double (value,  self->priv->x1);
609 		break;
610 
611 	case PROP_Y1:
612 		g_value_set_double (value,  self->priv->y1);
613 		break;
614 
615 	case PROP_X2:
616 		g_value_set_double (value,  self->priv->x2);
617 		break;
618 
619 	case PROP_Y2:
620 		g_value_set_double (value,  self->priv->y2);
621 		break;
622 
623 	case PROP_FILL_COLOR_RGBA:
624 		g_value_set_boxed (value,  &self->priv->fill_color);
625 		break;
626 
627 	case PROP_OUTLINE_COLOR_RGBA:
628 		g_value_set_boxed (value,  &self->priv->outline_color);
629 		break;
630 
631 	case PROP_OUTLINE_STIPPLING:
632 		g_value_set_boolean (value, self->priv->outline_stippling);
633 		break;
634 	case PROP_WIDTH_PIXELS:
635 		g_value_set_uint (value, self->priv->width);
636 		break;
637 	default:
638 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
639 		break;
640 	}
641 }
642 
643 static void
644 nautilus_selection_canvas_item_class_init (NautilusSelectionCanvasItemClass *klass)
645 {
646 	EelCanvasItemClass *item_class;
647 	GObjectClass *gobject_class;
648 
649 	gobject_class = G_OBJECT_CLASS (klass);
650 	item_class = EEL_CANVAS_ITEM_CLASS (klass);
651 
652 	gobject_class->set_property = nautilus_selection_canvas_item_set_property;
653 	gobject_class->get_property = nautilus_selection_canvas_item_get_property;
654 	gobject_class->dispose = nautilus_selection_canvas_item_dispose;
655 
656 	item_class->draw = nautilus_selection_canvas_item_draw;
657 	item_class->point = nautilus_selection_canvas_item_point;
658 	item_class->update = nautilus_selection_canvas_item_update;
659 	item_class->bounds = nautilus_selection_canvas_item_bounds;
660 	item_class->translate = nautilus_selection_canvas_item_translate;
661 
662 	properties[PROP_X1] = 
663                  g_param_spec_double ("x1", NULL, NULL,
664 				      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
665 				      G_PARAM_READWRITE);
666 	properties[PROP_Y1] =
667                  g_param_spec_double ("y1", NULL, NULL,
668 				      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
669 				      G_PARAM_READWRITE);
670 	properties[PROP_X2] =
671 		g_param_spec_double ("x2", NULL, NULL,
672 				      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
673 				      G_PARAM_READWRITE);
674 	properties[PROP_Y2] =
675 		g_param_spec_double ("y2", NULL, NULL,
676 				      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
677 				      G_PARAM_READWRITE);
678 	properties[PROP_FILL_COLOR_RGBA] = 
679                  g_param_spec_boxed ("fill-color-rgba", NULL, NULL,
680 				     GDK_TYPE_RGBA,
681 				     G_PARAM_READWRITE);
682 	properties[PROP_OUTLINE_COLOR_RGBA] =
683 		g_param_spec_boxed ("outline-color-rgba", NULL, NULL,
684 				     GDK_TYPE_RGBA,
685 				     G_PARAM_READWRITE);
686 	properties[PROP_OUTLINE_STIPPLING] =
687 		 g_param_spec_boolean ("outline-stippling", NULL, NULL,
688 				       FALSE, G_PARAM_READWRITE);
689 	properties[PROP_WIDTH_PIXELS] =
690                  g_param_spec_uint ("width-pixels", NULL, NULL,
691 				    0, G_MAXUINT, 0,
692 				    G_PARAM_READWRITE);
693 
694 	g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
695 	g_type_class_add_private (klass, sizeof (NautilusSelectionCanvasItemDetails));
696 }
697 
698 static void
699 nautilus_selection_canvas_item_init (NautilusSelectionCanvasItem *self)
700 {
701 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NAUTILUS_TYPE_SELECTION_CANVAS_ITEM,
702 						  NautilusSelectionCanvasItemDetails);
703 }