Index: libgnomecanvas/gnome-canvas.c
===================================================================
RCS file: /cvs/gnome/libgnomecanvas/libgnomecanvas/gnome-canvas.c,v
retrieving revision 1.170
diff -u -r1.170 gnome-canvas.c
--- libgnomecanvas/gnome-canvas.c	25 Dec 2004 16:11:07 -0000	1.170
+++ libgnomecanvas/gnome-canvas.c	8 Feb 2005 21:45:08 -0000
@@ -78,6 +78,7 @@
 #include <math.h>
 #include <string.h>
 #include <stdio.h>
+#include <gobject/gvaluecollector.h>
 #include <gdk/gdkprivate.h>
 #include <gtk/gtkmain.h>
 #include <gtk/gtksignal.h>
@@ -113,7 +114,8 @@
 
 enum {
 	ITEM_PROP_0,
-	ITEM_PROP_PARENT
+	ITEM_PROP_PARENT,
+	ITEM_PROP_CANVAS
 };
 
 enum {
@@ -189,38 +191,110 @@
  * Return value: The newly-created item.
  **/
 GnomeCanvasItem *
-gnome_canvas_item_new (GnomeCanvasGroup *parent, GType type, const gchar *first_arg_name, ...)
+gnome_canvas_item_new (GnomeCanvasGroup *parent, GType object_type, const gchar *first_property_name, ...)
 {
 	GnomeCanvasItem *item;
-	va_list args;
+	GObjectClass *klass;
+	GParameter *params;
+	const gchar *name;
+	guint n_params = 0, n_alloced_params = 16;
+	va_list var_args;
 
 	g_return_val_if_fail (GNOME_IS_CANVAS_GROUP (parent), NULL);
-	g_return_val_if_fail (g_type_is_a (type, gnome_canvas_item_get_type ()), NULL);
+	g_return_val_if_fail (g_type_is_a (object_type, gnome_canvas_item_get_type ()), NULL);
 
-	item = GNOME_CANVAS_ITEM (g_object_new (type, NULL));
+	if (!first_property_name)
+		return g_object_new (object_type,
+				     "canvas", GNOME_CANVAS_ITEM(parent)->canvas,
+				     "parent", parent,
+				     NULL);
+
+	klass = g_type_class_ref (object_type);
+
+	params = g_new (GParameter, n_alloced_params);
+
+	params[n_params].name = "canvas";
+	params[n_params].value.g_type = 0;
+	g_value_init (&params[n_params].value, gnome_canvas_get_type());
+	g_value_set_object(&params[n_params].value,
+			   G_OBJECT(GNOME_CANVAS_ITEM(parent)->canvas));
+	n_params++;
+
+	params[n_params].name = "parent";
+	params[n_params].value.g_type = 0;
+	g_value_init (&params[n_params].value, gnome_canvas_group_get_type());
+	g_value_set_object(&params[n_params].value,
+			   G_OBJECT(parent));
+	n_params++;
+
+	name = first_property_name;
+	va_start (var_args, first_property_name);
+	while (name) {
+		gchar *error = NULL;
+		GParamSpec *pspec = g_object_class_find_property(klass, name);
+		if (!pspec) {
+			g_warning ("%s: object class `%s' has no property named `%s'",
+				   G_STRFUNC,
+				   g_type_name (object_type),
+				   name);
+			break;
+		}
+		if (n_params >= n_alloced_params) {
+			n_alloced_params += 16;
+			params = g_renew (GParameter, params, n_alloced_params);
+				}
+		params[n_params].name = name;
+		params[n_params].value.g_type = 0;
+		g_value_init (&params[n_params].value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+		G_VALUE_COLLECT (&params[n_params].value, var_args, 0, &error);
+		if (error) {
+			g_warning ("%s: %s", G_STRFUNC, error);
+			g_free (error);
+			g_value_unset (&params[n_params].value);
+			break;
+		}
+		n_params++;
+		name = va_arg (var_args, gchar*);
+	}
+	va_end (var_args);
 
-	va_start (args, first_arg_name);
-	gnome_canvas_item_construct (item, parent, first_arg_name, args);
-	va_end (args);
+	item = GNOME_CANVAS_ITEM (g_object_newv (object_type, n_params, params));
 
-	return item;
-}
+	while (n_params--)
+		g_value_unset (&params[n_params].value);
+	g_free (params);
 
+	g_type_class_unref (klass);
 
-/* Performs post-creation operations on a canvas item (adding it to its parent
- * group, etc.)
- */
-static void
-item_post_create_setup (GnomeCanvasItem *item)
-{
-	GtkObject *obj;
-
-	obj = GTK_OBJECT (item);
+	return item;
+}
 
-	group_add (GNOME_CANVAS_GROUP (item->parent), item);
 
-	gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2 + 1, item->y2 + 1);
-	item->canvas->need_repick = TRUE;
+static GObject *
+gnome_canvas_item_constructor (GType                  type,
+			       guint                  n_construct_properties,
+			       GObjectConstructParam *construct_properties)
+{
+  GObject *obj;
+  {
+    /* Invoke parent constructor. */
+    GnomeCanvasItemClass *klass;
+    GObjectClass *parent_class;
+    klass = GNOME_CANVAS_ITEM_CLASS (g_type_class_peek (gnome_canvas_item_get_type()));
+    parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
+    obj = parent_class->constructor (type,
+                                     n_construct_properties,
+                                     construct_properties);
+  }
+  GnomeCanvasItem *item = GNOME_CANVAS_ITEM(obj);
+  if (item->parent) {
+	  group_add (GNOME_CANVAS_GROUP (item->parent), item);
+	  gnome_canvas_request_redraw (item->canvas,
+				       item->x1, item->y1,
+				       item->x2 + 1, item->y2 + 1);
+	  item->canvas->need_repick = TRUE;
+  }
+  return obj;
 }
 
 /* Set_property handler for canvas items */
@@ -233,17 +307,14 @@
 	g_return_if_fail (GNOME_IS_CANVAS_ITEM (gobject));
 
 	item = GNOME_CANVAS_ITEM (gobject);
-
 	switch (param_id) {
 	case ITEM_PROP_PARENT:
-		if (item->parent != NULL) {
-		    g_warning ("Cannot set `parent' argument after item has "
-			       "already been constructed.");
-		} else if (g_value_get_object (value)) {
+		if (g_value_get_object (value))
 			item->parent = GNOME_CANVAS_ITEM (g_value_get_object (value));
-			item->canvas = item->parent->canvas;
-			item_post_create_setup (item);
-		}
+		break;
+	case ITEM_PROP_CANVAS:
+		if (g_value_get_object (value))
+			item->canvas = GNOME_CANVAS (g_value_get_object (value));
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
@@ -266,38 +337,15 @@
 	case ITEM_PROP_PARENT:
 		g_value_set_object (value, item->parent);
 		break;
-
+	case ITEM_PROP_CANVAS:
+		g_value_set_object (value, item->canvas);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
 		break;
 	}
 }
 
-/**
- * gnome_canvas_item_construct:
- * @item: An unconstructed canvas item.
- * @parent: The parent group for the item.
- * @first_arg_name: The name of the first argument for configuring the item.
- * @args: The list of arguments used to configure the item.
- *
- * Constructs a canvas item; meant for use only by item implementations.
- **/
-void
-gnome_canvas_item_construct (GnomeCanvasItem *item, GnomeCanvasGroup *parent,
-			     const gchar *first_arg_name, va_list args)
-{
-	g_return_if_fail (GNOME_IS_CANVAS_GROUP (parent));
-	g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
-
-	item->parent = GNOME_CANVAS_ITEM (parent);
-	item->canvas = item->parent->canvas;
-
-	g_object_set_valist (G_OBJECT (item), first_arg_name, args);
-
-	item_post_create_setup (item);
-}
-
-
 /* If the item is visible, requests a redraw of it. */
 static void
 redraw_if_visible (GnomeCanvasItem *item)
@@ -2117,10 +2165,13 @@
 
 	/* Disable the gtk+ double buffering since the canvas uses it's own. */
 	gtk_widget_set_double_buffered (GTK_WIDGET (canvas), FALSE);
-	
+
 	/* Create the root item as a special case */
 
-	canvas->root = GNOME_CANVAS_ITEM (g_object_new (gnome_canvas_group_get_type (), NULL));
+	canvas->root = GNOME_CANVAS_ITEM (g_object_new (gnome_canvas_group_get_type (),
+							"canvas", canvas,
+							"parent", NULL,
+							NULL));
 	canvas->root->canvas = canvas;
 
 	g_object_ref (canvas->root);
@@ -4057,6 +4108,7 @@
 
 	item_parent_class = g_type_class_peek_parent (class);
 
+	gobject_class->constructor = gnome_canvas_item_constructor;
 	gobject_class->set_property = gnome_canvas_item_set_property;
 	gobject_class->get_property = gnome_canvas_item_get_property;
 
@@ -4064,7 +4116,13 @@
 		(gobject_class, ITEM_PROP_PARENT,
 		 g_param_spec_object ("parent", NULL, NULL,
 				      GNOME_TYPE_CANVAS_ITEM,
-				      (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+				      (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
+
+	g_object_class_install_property
+		(gobject_class, ITEM_PROP_CANVAS,
+		 g_param_spec_object ("canvas", NULL, NULL,
+				      GNOME_TYPE_CANVAS,
+				      (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
 
 	item_signals[ITEM_EVENT] =
 		g_signal_new ("event",
Index: libgnomecanvas/gnome-canvas.h
===================================================================
RCS file: /cvs/gnome/libgnomecanvas/libgnomecanvas/gnome-canvas.h,v
retrieving revision 1.64
diff -u -r1.64 gnome-canvas.h
--- libgnomecanvas/gnome-canvas.h	18 Apr 2002 07:44:46 -0000	1.64
+++ libgnomecanvas/gnome-canvas.h	8 Feb 2005 21:45:09 -0000
@@ -234,12 +234,9 @@
  * automatically inserted at the top of the specified canvas group.  The last
  * argument must be a NULL pointer.
  */
-GnomeCanvasItem *gnome_canvas_item_new (GnomeCanvasGroup *parent, GType type,
-					const gchar *first_arg_name, ...);
-
-/* Constructors for use in derived classes and language wrappers */
-void gnome_canvas_item_construct (GnomeCanvasItem *item, GnomeCanvasGroup *parent,
-				  const gchar *first_arg_name, va_list args);
+GnomeCanvasItem *gnome_canvas_item_new (GnomeCanvasGroup *parent,
+					GType object_type,
+					const gchar *first_property_name, ...);
 
 /* Configure an item using the standard Gtk argument mechanism.  The last
  * argument must be a NULL pointer.
