[cairo-commit] goocanvas/demo Makefile.am, NONE, 1.1 demo-arrowhead.c, NONE, 1.1 demo-events.c, NONE, 1.1 demo-features.c, NONE, 1.1 demo-fifteen.c, NONE, 1.1 demo-grabs.c, NONE, 1.1 demo-paths.c, NONE, 1.1 demo-scalability.c, NONE, 1.1 demo.c, NONE, 1.1 flower.png, NONE, 1.1 toroid.png, NONE, 1.1

Damon Chaplin commit at pdx.freedesktop.org
Wed Apr 12 03:45:54 PDT 2006


Committed by: damon

Update of /cvs/cairo/goocanvas/demo
In directory kemper:/tmp/cvs-serv29600/demo

Added Files:
	Makefile.am demo-arrowhead.c demo-events.c demo-features.c 
	demo-fifteen.c demo-grabs.c demo-paths.c demo-scalability.c 
	demo.c flower.png toroid.png 
Log Message:
2006-04-12  Damon Chaplin  <damon at gnome.org>

	* demo/*: moved all the demo code here.

	* src/goocanvas.h: new main header to include all the public headers.



--- NEW FILE: Makefile.am ---
## Process this file with automake to produce Makefile.in

INCLUDES = \
	-DG_DISABLE_DEPRECATED -DPANGO_DISABLE_DEPRECATED \
	-DGDK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED \
	-DGTK_DISABLE_DEPRECATED \
	-I$(top_srcdir)/src \
	@PACKAGE_CFLAGS@

noinst_PROGRAMS = demo

demo_SOURCES = \
	demo.c demo-fifteen.c demo-scalability.c demo-grabs.c \
	demo-arrowhead.c demo-features.c demo-events.c demo-paths.c

demo_LDADD = $(top_builddir)/src/libgoocanvas.la @PACKAGE_LIBS@ $(INTLLIBS)

EXTRA_DIST = flower.png toroid.png


--- NEW FILE: demo-arrowhead.c ---
#include <config.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <goocanvas.h>

#define LEFT    50.0
#define RIGHT  350.0
#define MIDDLE 150.0
#define DEFAULT_WIDTH   2
#define DEFAULT_SHAPE_A 4
#define DEFAULT_SHAPE_B 5
#define DEFAULT_SHAPE_C 4


static void
set_dimension (GooCanvasView *canvas, char *arrow_name, char *text_name,
	       double x1, double y1, double x2, double y2,
	       double tx, double ty, int dim)
{
	GooCanvasPoints *points;
	char buf[100];

	points = goo_canvas_points_new (2);
	points->coords[0] = x1;
	points->coords[1] = y1;
	points->coords[2] = x2;
	points->coords[3] = y2;

	g_object_set (g_object_get_data (G_OBJECT (canvas), arrow_name),
		      "points", points,
		      NULL);

	sprintf (buf, "%d", dim);
	g_object_set (g_object_get_data (G_OBJECT (canvas), text_name),
		      "text", buf,
		      "x", tx,
		      "y", ty,
		      NULL);

	goo_canvas_points_unref (points);
}

static void
move_drag_box (GooCanvasItem *item, double x, double y)
{
	g_object_set (item,
		      "x", x - 5.0,
		      "y", y - 5.0,
		      NULL);
}


static void
set_arrow_shape (GooCanvasView *canvas)
{
	int width;
	int shape_a, shape_b, shape_c;
	GooCanvasPoints *points;
	char buf[100];

	width = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (canvas), "width"));
	shape_a = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (canvas), "shape_a"));
	shape_b = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (canvas), "shape_b"));
	shape_c = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (canvas), "shape_c"));

	/* Big arrow */

	g_object_set (g_object_get_data (G_OBJECT (canvas), "big_arrow"),
		      "line-width", 10.0 * width,
		      "arrow-tip-length", (double) (shape_a),
		      "arrow-length", (double) (shape_b),
		      "arrow-width", (double) (shape_c),
		      NULL);

	/* Outline */

	points = goo_canvas_points_new (5);
	points->coords[0] = RIGHT - 10 * shape_a * width;
	points->coords[1] = MIDDLE - 10 * width / 2;
	points->coords[2] = RIGHT - 10 * shape_b * width;
	points->coords[3] = MIDDLE - 10 * (shape_c * width / 2.0);
	points->coords[4] = RIGHT;
	points->coords[5] = MIDDLE;
	points->coords[6] = points->coords[2];
	points->coords[7] = MIDDLE + 10 * (shape_c * width / 2.0);
	points->coords[8] = points->coords[0];
	points->coords[9] = MIDDLE + 10 * width / 2;
	g_object_set (g_object_get_data (G_OBJECT (canvas), "outline"),
		      "points", points,
		      NULL);
	goo_canvas_points_unref (points);

	/* Drag boxes */

	move_drag_box (g_object_get_data (G_OBJECT (canvas), "width_drag_box"),
		       LEFT,
		       MIDDLE - 10 * width / 2.0);

	move_drag_box (g_object_get_data (G_OBJECT (canvas), "shape_a_drag_box"),
		       RIGHT - 10 * shape_a * width,
		       MIDDLE);

	move_drag_box (g_object_get_data (G_OBJECT (canvas), "shape_b_c_drag_box"),
		       RIGHT - 10 * shape_b * width,
		       MIDDLE - 10 * (shape_c * width / 2.0));

	/* Dimensions */

	set_dimension (canvas, "width_arrow", "width_text",
		       LEFT - 10,
		       MIDDLE - 10 * width / 2.0,
		       LEFT - 10,
		       MIDDLE + 10 * width / 2.0,
		       LEFT - 15,
		       MIDDLE,
		       width);

	set_dimension (canvas, "shape_a_arrow", "shape_a_text",
		       RIGHT - 10 * shape_a * width,
		       MIDDLE + 10 * (shape_c * width / 2.0) + 10,
		       RIGHT,
		       MIDDLE + 10 * (shape_c * width / 2.0) + 10,
		       RIGHT - 10 * shape_a * width / 2.0,
		       MIDDLE + 10 * (shape_c * width / 2.0) + 15,
		       shape_a);

	set_dimension (canvas, "shape_b_arrow", "shape_b_text",
		       RIGHT - 10 * shape_b * width,
		       MIDDLE + 10 * (shape_c * width / 2.0) + 35,
		       RIGHT,
		       MIDDLE + 10 * (shape_c * width / 2.0) + 35,
		       RIGHT - 10 * shape_b * width / 2.0,
		       MIDDLE + 10 * (shape_c * width / 2.0) + 40,
		       shape_b);

	set_dimension (canvas, "shape_c_arrow", "shape_c_text",
		       RIGHT + 10,
		       MIDDLE - 10 * shape_c * width / 2.0,
		       RIGHT + 10,
		       MIDDLE + 10 * shape_c * width / 2.0,
		       RIGHT + 15,
		       MIDDLE,
		       shape_c);

	/* Info */

	sprintf (buf, "line-width: %d", width);
	g_object_set (g_object_get_data (G_OBJECT (canvas), "width_info"),
		      "text", buf,
		      NULL);

	sprintf (buf, "arrow-tip-length: %d (* line-width)", shape_a);
	g_object_set (g_object_get_data (G_OBJECT (canvas), "shape_a_info"),
		      "text", buf,
		      NULL);

	sprintf (buf, "arrow-length: %d (* line-width)", shape_b);
	g_object_set (g_object_get_data (G_OBJECT (canvas), "shape_b_info"),
		      "text", buf,
		      NULL);
	sprintf (buf, "arrow-width: %d (* line-width)", shape_c);
	g_object_set (g_object_get_data (G_OBJECT (canvas), "shape_c_info"),
		      "text", buf,
		      NULL);

	/* Sample arrows */

	g_object_set (g_object_get_data (G_OBJECT (canvas), "sample_1"),
		      "line-width", (double) width,
		      "arrow-tip-length", (double) shape_a,
		      "arrow-length", (double) shape_b,
		      "arrow-width", (double) shape_c,
		      NULL);
	g_object_set (g_object_get_data (G_OBJECT (canvas), "sample_2"),
		      "line-width", (double) width,
		      "arrow-tip-length", (double) shape_a,
		      "arrow-length", (double) shape_b,
		      "arrow-width", (double) shape_c,
		      NULL);
	g_object_set (g_object_get_data (G_OBJECT (canvas), "sample_3"),
		      "line-width", (double) width,
		      "arrow-tip-length", (double) shape_a,
		      "arrow-length", (double) shape_b,
		      "arrow-width", (double) shape_c,
		      NULL);
}


static void
create_drag_box (GtkWidget *canvas,
		 GooCanvasItem *root,
		 char *box_name)
{
	GooCanvasItem *box;

	box = goo_canvas_rect_new (root, 0, 0, 10, 10,
				   "fill_color", "black",
				   "stroke_color", "black",
				   "line_width", 1.0,
				   NULL);
	g_object_set_data (G_OBJECT (canvas), box_name, box);
}


static void
create_dimension (GtkWidget *canvas,
		  GooCanvasItem *root,
		  char *arrow_name,
		  char *text_name,
		  GtkAnchorType anchor)
{
	GooCanvasItem *item;

	item = goo_canvas_polyline_new (root, FALSE, 0,
				      "fill_color", "black",
				      "start-arrow", TRUE,
				      "end-arrow", TRUE,
				      NULL);
	g_object_set_data (G_OBJECT (canvas), arrow_name, item);

	item = goo_canvas_text_new (root, NULL, 0, 0, -1, anchor,
				    "fill_color", "black",
				    "font", "Sans 12",
				    NULL);
	g_object_set_data (G_OBJECT (canvas), text_name, item);
}

static void
create_info (GtkWidget *canvas,
	     GooCanvasItem *root,
	     char *info_name,
	     double x,
	     double y)
{
	GooCanvasItem *item;

	item = goo_canvas_text_new (root, NULL, x, y, -1, GTK_ANCHOR_NW,
				    "fill_color", "black",
				    "font", "Sans 14",
				    NULL);
	g_object_set_data (G_OBJECT (canvas), info_name, item);
}

static void
create_sample_arrow (GtkWidget *canvas,
		     GooCanvasItem *root,
		     char *sample_name,
		     double x1,
		     double y1,
		     double x2,
		     double y2)
{
	GooCanvasItem *item;

	item = goo_canvas_polyline_new_line (root, x1, y1, x2, y2,
					     "start-arrow", TRUE,
					     "end-arrow", TRUE,
					     NULL);
	g_object_set_data (G_OBJECT (canvas), sample_name, item);
}


static gboolean
on_enter_notify (GooCanvasItemView *view,
		 GooCanvasItemView *target,
		 GdkEventCrossing *event,
		 gpointer data)
{
  GooCanvasItem *item = goo_canvas_item_view_get_item (target);

  g_object_set (item,
		"fill_color", "red",
		NULL);

  return TRUE;
}


static gboolean
on_leave_notify (GooCanvasItemView *view,
		 GooCanvasItemView *target,
		 GdkEvent *event,
		 gpointer data)
{
  GooCanvasItem *item = goo_canvas_item_view_get_item (target);

  g_object_set (item,
		"fill_color", "black",
		NULL);

  return TRUE;
}


static gboolean
on_button_press (GooCanvasItemView *view,
		 GooCanvasItemView *target,
		 GdkEventButton *event,
		 gpointer data)
{
  GooCanvasView *canvas_view;
  GdkCursor *fleur;

  fleur = gdk_cursor_new (GDK_FLEUR);
  canvas_view = goo_canvas_item_view_get_canvas_view (view);
  goo_canvas_view_pointer_grab (canvas_view, view,
				GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
				fleur,
				event->time);
  gdk_cursor_unref (fleur);

  return TRUE;
}


static gboolean
on_button_release (GooCanvasItemView *view,
		   GooCanvasItemView *target,
		   GdkEventButton *event,
		   gpointer data)
{
  GooCanvasView *canvas_view;

  canvas_view = goo_canvas_item_view_get_canvas_view (view);
  goo_canvas_view_pointer_ungrab (canvas_view, view, event->time);

  return TRUE;
}


static gboolean
on_motion (GooCanvasItemView *view,
	   GooCanvasItemView *target,
	   GdkEventMotion *event,
	   gpointer data)
{
  GooCanvasView *canvas = goo_canvas_item_view_get_canvas_view (view);
  GooCanvasItem *item = goo_canvas_item_view_get_item (target);
  int x, y, width, shape_a, shape_b, shape_c;
  gboolean change = FALSE;

  if (!(event->state & GDK_BUTTON1_MASK))
    return FALSE;

  if (item == g_object_get_data (G_OBJECT (canvas), "width_drag_box"))
    {
      y = event->y;
      width = (MIDDLE - y) / 5;
      if (width < 0)
	return FALSE;
      g_object_set_data (G_OBJECT (canvas), "width", GINT_TO_POINTER (width));
      set_arrow_shape (canvas);
    }
  else if (item == g_object_get_data (G_OBJECT (canvas), "shape_a_drag_box"))
    {
      x = event->x;
      width = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (canvas), "width"));
      shape_a = (RIGHT - x) / 10 / width;
      if ((shape_a < 0) || (shape_a > 30))
	return FALSE;
      g_object_set_data (G_OBJECT (canvas), "shape_a",
			 GINT_TO_POINTER (shape_a));
      set_arrow_shape (canvas);
    }
  else if (item == g_object_get_data (G_OBJECT (canvas), "shape_b_c_drag_box"))
    {
      width = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (canvas), "width"));

      x = event->x;
      shape_b = (RIGHT - x) / 10 / width;
      if ((shape_b >= 0) && (shape_b <= 30)) {
	g_object_set_data (G_OBJECT (canvas), "shape_b",
			   GINT_TO_POINTER (shape_b));
	change = TRUE;
      }

      y = event->y;
      shape_c = (MIDDLE - y) * 2 / 10 / width;
      if (shape_c >= 0) {
	g_object_set_data (G_OBJECT (canvas), "shape_c",
			   GINT_TO_POINTER (shape_c));
	change = TRUE;
      }

      if (change)
	set_arrow_shape (canvas);
    }

  return TRUE;
}


static void
on_item_view_created (GooCanvasView     *view,
		      GooCanvasItemView *item_view,
		      GooCanvasItem     *item,
		      gpointer           data)
{
  if (GOO_IS_CANVAS_RECT (item))
    {
      g_signal_connect (item_view, "enter_notify_event",
			(GtkSignalFunc) on_enter_notify,
			NULL);
      g_signal_connect (item_view, "leave_notify_event",
			(GtkSignalFunc) on_leave_notify,
			NULL);
      g_signal_connect (item_view, "button_press_event",
			(GtkSignalFunc) on_button_press,
			NULL);
      g_signal_connect (item_view, "button_release_event",
			(GtkSignalFunc) on_button_release,
			NULL);
      g_signal_connect (item_view, "motion_notify_event",
			(GtkSignalFunc) on_motion,
			NULL);
    }
}


GtkWidget *
create_canvas_arrowhead (void)
{
	GtkWidget *vbox;
	GtkWidget *w;
	GtkWidget *frame;
	GtkWidget *canvas;
	GooCanvasModelSimple *canvas_model;
	GooCanvasItem *root, *item;

	vbox = gtk_vbox_new (FALSE, 4);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
	gtk_widget_show (vbox);

	w = gtk_label_new ("This demo allows you to edit arrowhead shapes.  Drag the little boxes\n"
			   "to change the shape of the line and its arrowhead.  You can see the\n"
			   "arrows at their normal scale on the right hand side of the window.");
	gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
	gtk_widget_show (w);

	w = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
	gtk_box_pack_start (GTK_BOX (vbox), w, TRUE, TRUE, 0);
	gtk_widget_show (w);

	frame = gtk_frame_new (NULL);
	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
	gtk_container_add (GTK_CONTAINER (w), frame);
	gtk_widget_show (frame);

	canvas = goo_canvas_view_new ();

	g_signal_connect (canvas, "item_view_created",
			  (GtkSignalFunc) on_item_view_created,
			  NULL);

	canvas_model = goo_canvas_model_simple_new ();

	goo_canvas_view_set_model (GOO_CANVAS_VIEW (canvas),
				   GOO_CANVAS_MODEL (canvas_model));
	g_object_unref (canvas_model);

	root = goo_canvas_model_get_root_item (GOO_CANVAS_MODEL (canvas_model));
	gtk_widget_set_size_request (canvas, 500, 350);
	goo_canvas_view_set_bounds (GOO_CANVAS_VIEW (canvas), 0, 0, 500, 350);
	gtk_container_add (GTK_CONTAINER (frame), canvas);
	gtk_widget_show (canvas);


	g_object_set_data (G_OBJECT (canvas), "width",
			   GINT_TO_POINTER (DEFAULT_WIDTH));
	g_object_set_data (G_OBJECT (canvas), "shape_a",
			   GINT_TO_POINTER (DEFAULT_SHAPE_A));
	g_object_set_data (G_OBJECT (canvas), "shape_b",
			   GINT_TO_POINTER (DEFAULT_SHAPE_B));
	g_object_set_data (G_OBJECT (canvas), "shape_c",
			   GINT_TO_POINTER (DEFAULT_SHAPE_C));

	/* Big arrow */

	item = goo_canvas_polyline_new_line (root,
					     LEFT, MIDDLE, RIGHT, MIDDLE,
					     "stroke_color", "mediumseagreen",
					     "end-arrow", TRUE,
					     NULL);
	g_object_set_data (G_OBJECT (canvas), "big_arrow", item);

	/* Arrow outline */

	item = goo_canvas_polyline_new (root, TRUE, 0,
					"stroke_color", "black",
					"line-width", 2.0,
					"line-cap", CAIRO_LINE_CAP_ROUND,
					"line-join", CAIRO_LINE_JOIN_ROUND,
					NULL);
	g_object_set_data (G_OBJECT (canvas), "outline", item);

	/* Drag boxes */

	create_drag_box (canvas, root, "width_drag_box");
	create_drag_box (canvas, root, "shape_a_drag_box");
	create_drag_box (canvas, root, "shape_b_c_drag_box");

	/* Dimensions */

	create_dimension (canvas, root, "width_arrow", "width_text", GTK_ANCHOR_E);
	create_dimension (canvas, root, "shape_a_arrow", "shape_a_text", GTK_ANCHOR_N);
	create_dimension (canvas, root, "shape_b_arrow", "shape_b_text", GTK_ANCHOR_N);
	create_dimension (canvas, root, "shape_c_arrow", "shape_c_text", GTK_ANCHOR_W);

	/* Info */

	create_info (canvas, root, "width_info", LEFT, 260);
	create_info (canvas, root, "shape_a_info", LEFT, 280);
	create_info (canvas, root, "shape_b_info", LEFT, 300);
	create_info (canvas, root, "shape_c_info", LEFT, 320);

	/* Division line */

	goo_canvas_polyline_new_line (root, RIGHT + 50, 0, RIGHT + 50, 1000,
				      "fill_color", "black",
				      "line-width", 2.0,
				      NULL);

	/* Sample arrows */

	create_sample_arrow (canvas, root, "sample_1",
			     RIGHT + 100, 30, RIGHT + 100, MIDDLE - 30);
	create_sample_arrow (canvas, root, "sample_2",
			     RIGHT + 70, MIDDLE, RIGHT + 130, MIDDLE);
	create_sample_arrow (canvas, root, "sample_3",
			     RIGHT + 70, MIDDLE + 30, RIGHT + 130, MIDDLE + 120);

	/* Done! */
	
	set_arrow_shape (GOO_CANVAS_VIEW (canvas));
	return vbox;
}

--- NEW FILE: demo-events.c ---
#include <config.h>
#include <string.h>
#include <gtk/gtk.h>
#include <goocanvas.h>


static gboolean
on_motion_notify (GooCanvasItemView *view,
		  GooCanvasItemView *target,
		  GdkEventMotion *event,
		  gpointer data)
{
  GooCanvasItem *item = NULL;
  char *item_id = NULL;

  if (target)
    item = goo_canvas_item_view_get_item (target);

  if (item)
    item_id = g_object_get_data (G_OBJECT (item), "id");

  if (item_id)
    g_print ("%s item received 'motion-notify' signal\n", item_id);

  return FALSE;
}


static void
on_item_view_created (GooCanvasView     *view,
		      GooCanvasItemView *item_view,
		      GooCanvasItem     *item,
		      gpointer           data)
{
  g_signal_connect (item_view, "motion_notify_event",
		    (GtkSignalFunc) on_motion_notify, NULL);
}


static void
create_events_area (GooCanvasModelSimple   *canvas_model,
		    gint                    area_num,
		    GooCanvasPointerEvents  pointer_events,
		    gchar                  *label)
{
  gint row = area_num / 3, col = area_num % 3;
  gdouble x = col * 200, y = row * 150;
  GooCanvasItem *root, *rect;
  char *view_id;
  GooCairoLineDash *dash;

  root = goo_canvas_model_get_root_item (GOO_CANVAS_MODEL (canvas_model));

  dash = goo_cairo_line_dash_new (2, 5.0, 5.0);

  /* Create invisible item. */
  rect = goo_canvas_rect_new (root, x + 45, y + 35, 30, 30,
			      "fill-color", "red",
			      "visibility", GOO_CANVAS_ITEM_INVISIBLE,
			      "line-width", 5.0,
			      "pointer-events", pointer_events,
			      NULL);
  view_id = g_strdup_printf ("%s invisible", label);
  g_object_set_data_full (G_OBJECT (rect), "id", view_id, g_free);

  /* Display a thin rect around it to indicate it is there. */
#if 1
  rect = goo_canvas_rect_new (root, x + 42.5, y + 32.5, 36, 36,
			      "line-dash", dash,
			      "line-width", 1.0,
			      "stroke-color", "gray",
			      NULL);
#endif

  /* Create unpainted item. */
  rect = goo_canvas_rect_new (root, x + 85, y + 35, 30, 30,
			      "stroke-pattern", NULL,
			      "line-width", 5.0,
			      "pointer-events", pointer_events,
			      NULL);
  view_id = g_strdup_printf ("%s unpainted", label);
  g_object_set_data_full (G_OBJECT (rect), "id", view_id, g_free);

  /* Display a thin rect around it to indicate it is there. */
#if 1
  rect = goo_canvas_rect_new (root, x + 82.5, y + 32.5, 36, 36,
			      "line-dash", dash,
			      "line-width", 1.0,
			      "stroke-color", "gray",
			      NULL);
#endif

  /* Create stroked item. */
  rect = goo_canvas_rect_new (root, x + 125, y + 35, 30, 30,
			      "line-width", 5.0,
			      "pointer-events", pointer_events,
			      NULL);
  view_id = g_strdup_printf ("%s stroked", label);
  g_object_set_data_full (G_OBJECT (rect), "id", view_id, g_free);

  /* Create filled item. */
  rect = goo_canvas_rect_new (root, x + 60, y + 75, 30, 30,
			      "fill-color", "red",
			      "stroke-pattern", NULL,
			      "line-width", 5.0,
			      "pointer-events", pointer_events,
			      NULL);
  view_id = g_strdup_printf ("%s filled", label);
  g_object_set_data_full (G_OBJECT (rect), "id", view_id, g_free);

  /* Create stroked & filled item. */
  rect = goo_canvas_rect_new (root, x + 100, y + 75, 30, 30,
			      "fill-color", "red",
			      "line-width", 5.0,
			      "pointer-events", pointer_events,
			      NULL);
  view_id = g_strdup_printf ("%s stroked & filled", label);
  g_object_set_data_full (G_OBJECT (rect), "id", view_id, g_free);

  goo_canvas_text_new (root, label, x + 100, y + 130, -1, GTK_ANCHOR_CENTER,
		       "font", "Sans 12",
		       "fill-color", "blue",
		       NULL);

  goo_cairo_line_dash_unref (dash);
}


GtkWidget *
create_events_page (void)
{
  GtkWidget *vbox, *alignment, *frame, *label, *canvas;
  GooCanvasModelSimple *canvas_model;

  vbox = gtk_vbox_new (FALSE, 4);
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
  gtk_widget_show (vbox);

  /* Instructions */

  label = gtk_label_new ("Move the mouse over the items to check they receive the right motion events.\nThe first 2 items in each group are 1) invisible and 2) visible but unpainted.");
  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
  gtk_widget_show (label);

  /* Frame and canvas */

  alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
  gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
  gtk_widget_show (alignment);

  frame = gtk_frame_new (NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
  gtk_container_add (GTK_CONTAINER (alignment), frame);
  gtk_widget_show (frame);

  canvas = goo_canvas_view_new ();

  g_signal_connect (canvas, "item_view_created",
		    (GtkSignalFunc) on_item_view_created,
		    NULL);

  canvas_model = goo_canvas_model_simple_new ();

  gtk_widget_set_size_request (canvas, 600, 450);
  goo_canvas_view_set_bounds (GOO_CANVAS_VIEW (canvas), 0, 0, 600, 450);
  gtk_container_add (GTK_CONTAINER (frame), canvas);
  gtk_widget_show (canvas);

  create_events_area (canvas_model, 0, GOO_CANVAS_EVENTS_NONE, "none");
  create_events_area (canvas_model, 1, GOO_CANVAS_EVENTS_VISIBLE_PAINTED, "visible-painted");
  create_events_area (canvas_model, 2, GOO_CANVAS_EVENTS_VISIBLE_FILL, "visible-fill");
  create_events_area (canvas_model, 3, GOO_CANVAS_EVENTS_VISIBLE_STROKE, "visible-stroke");
  create_events_area (canvas_model, 4, GOO_CANVAS_EVENTS_VISIBLE, "visible");
  create_events_area (canvas_model, 5, GOO_CANVAS_EVENTS_PAINTED, "painted");
  create_events_area (canvas_model, 6, GOO_CANVAS_EVENTS_FILL, "fill");
  create_events_area (canvas_model, 7, GOO_CANVAS_EVENTS_STROKE, "stroke");
  create_events_area (canvas_model, 8, GOO_CANVAS_EVENTS_ALL, "all");

  goo_canvas_view_set_model (GOO_CANVAS_VIEW (canvas),
			     GOO_CANVAS_MODEL (canvas_model));
  g_object_unref (canvas_model);

  return vbox;
}

--- NEW FILE: demo-features.c ---
#include <config.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <goocanvas.h>


static gboolean
on_button_press (GooCanvasItemView *view,
		 GooCanvasItemView *target,
		 GdkEventButton *event,
		 gpointer data)
{
  GooCanvasItem *item = goo_canvas_item_view_get_item (view);
  GooCanvasItem *parent1, *parent2, *parent;
  int child_num;

  if (event->button != 1)
    return FALSE;

  parent1 = g_object_get_data (G_OBJECT (item), "parent1");
  parent2 = g_object_get_data (G_OBJECT (item), "parent2");

  parent = goo_canvas_item_get_parent (item);
  g_object_ref (item);
  child_num = goo_canvas_item_find_child (parent, item);
  goo_canvas_item_remove_child (parent, child_num);
  if (parent == parent1)
    goo_canvas_item_add_child (parent2, item, -1);
  else
    goo_canvas_item_add_child (parent1, item, -1);
  g_object_unref (item);

  return TRUE;
}


static void
on_item_view_created (GooCanvasView     *view,
		      GooCanvasItemView *item_view,
		      GooCanvasItem     *item,
		      gpointer           data)
{
  if (g_object_get_data (G_OBJECT (item), "parent1"))
    {
      g_signal_connect (item_view, "button_press_event",
			(GtkSignalFunc) on_button_press, NULL);
    }
}


GtkWidget *
create_canvas_features (void)
{
	GtkWidget *vbox;
	GtkWidget *w;
	GtkWidget *alignment;
	GtkWidget *frame;
	GtkWidget *canvas;
	GooCanvasModelSimple *canvas_model;
	GooCanvasItem *root, *item;
	GooCanvasItem *parent1;
	GooCanvasItem *parent2;
	GooCanvasItem *group;

	vbox = gtk_vbox_new (FALSE, 4);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
	gtk_widget_show (vbox);

	/* Instructions */

	w = gtk_label_new ("Reparent test:  click on the items to switch them between parents");
	gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
	gtk_widget_show (w);

	/* Frame and canvas */

	alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
	gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
	gtk_widget_show (alignment);

	frame = gtk_frame_new (NULL);
	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
	gtk_container_add (GTK_CONTAINER (alignment), frame);
	gtk_widget_show (frame);

	canvas = goo_canvas_view_new ();

	g_signal_connect (canvas, "item_view_created",
			  (GtkSignalFunc) on_item_view_created,
			  NULL);

	canvas_model = goo_canvas_model_simple_new ();

	root = goo_canvas_model_get_root_item (GOO_CANVAS_MODEL (canvas_model));
	gtk_widget_set_size_request (canvas, 400, 200);
	goo_canvas_view_set_bounds (GOO_CANVAS_VIEW (canvas), 0, 0, 300, 200);
	gtk_container_add (GTK_CONTAINER (frame), canvas);
	gtk_widget_show (canvas);

	/* First parent and box */

	parent1 = goo_canvas_group_new (root);

	goo_canvas_rect_new (parent1, 0, 0, 200, 200,
			     "fill_color", "tan",
			     NULL);

	/* Second parent and box */

	parent2 = goo_canvas_group_new (root);
	goo_canvas_item_translate (parent2, 200, 0);

	goo_canvas_rect_new (parent2, 0, 0, 200, 200,
			     "fill_color", "#204060",
			     NULL);

	/* Big circle to be reparented */

	item = goo_canvas_ellipse_new (parent1, 100, 100, 90, 90,
				       "stroke_color", "black",
				       "fill_color", "mediumseagreen",
				       "line-width", 3.0,
				       NULL);
	g_object_set_data (G_OBJECT (item), "parent1", parent1);
	g_object_set_data (G_OBJECT (item), "parent2", parent2);
#if 0
	g_signal_connect (G_OBJECT (item), "event",
			  (GtkSignalFunc) item_event,
			  NULL);
#endif

	/* A group to be reparented */

	group = goo_canvas_group_new (parent2);
	goo_canvas_item_translate (group, 100, 100);

	goo_canvas_ellipse_new (group, 0, 0, 50, 50,
				"stroke_color", "black",
				"fill_color", "wheat",
				"line_width", 3.0,
				NULL);
	goo_canvas_ellipse_new (group, 0, 0, 25, 25,
				"fill_color", "steelblue",
				NULL);

	g_object_set_data (G_OBJECT (group), "parent1", parent1);
	g_object_set_data (G_OBJECT (group), "parent2", parent2);
#if 0
	g_signal_connect (G_OBJECT (group), "event",
			    (GtkSignalFunc) item_event,
			    NULL);
#endif


	goo_canvas_view_set_model (GOO_CANVAS_VIEW (canvas),
				   GOO_CANVAS_MODEL (canvas_model));
	g_object_unref (canvas_model);


	/* Done */

	return vbox;
}

--- NEW FILE: demo-fifteen.c ---
#include <config.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <goocanvas.h>


#define PIECE_SIZE 50


static void
free_stuff (GtkObject *obj, gpointer data)
{
	g_free (data);
}

static void
test_win (GooCanvasItem **board)
{
	int i;
#if 0
	GtkWidget *dlg;
#endif

	for (i = 0; i < 15; i++)
		if (!board[i] || (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (board[i]), "piece_num")) != i))
			return;

#if 0
	dlg=gnome_ok_dialog ("You stud, you win!");
	gtk_window_set_modal(GTK_WINDOW(dlg),TRUE);
	gnome_dialog_run (GNOME_DIALOG (dlg));
#endif
}

static char *
get_piece_color (int piece)
{
	static char buf[50];
	int x, y;
	int r, g, b;

	y = piece / 4;
	x = piece % 4;

	r = ((4 - x) * 255) / 4;
	g = ((4 - y) * 255) / 4;
	b = 128;

	sprintf (buf, "#%02x%02x%02x", r, g, b);

	return buf;
}

static gboolean
piece_enter_notify (GooCanvasItemView *view,
		    GooCanvasItemView *target,
		    GdkEventCrossing *event,
		    gpointer data)
{
  GooCanvasItem *item, *text;

#if 0
  g_print ("In piece_enter_notify\n");
#endif

  item = (GooCanvasItem*) GOO_CANVAS_GROUP_VIEW (view)->group;
  text = g_object_get_data (G_OBJECT (item), "text");

  g_object_set (text,
		"fill_color", "white",
		NULL);

  return FALSE;
}


static gboolean
piece_leave_notify (GooCanvasItemView *view,
		    GooCanvasItemView *target,
		    GdkEvent *event,
		    gpointer data)
{
  GooCanvasItem *item, *text;

#if 0
  g_print ("In piece_leave_notify\n");
#endif

  item = (GooCanvasItem*) GOO_CANVAS_GROUP_VIEW (view)->group;
  text = g_object_get_data (G_OBJECT (item), "text");

  g_object_set (text,
		"fill_color", "black",
		NULL);

  return FALSE;
}


static gboolean
piece_button_press (GooCanvasItemView *view,
		    GooCanvasItemView *target,
		    GdkEventButton *event,
		    gpointer data)
{
        GooCanvasView *canvas;
	GooCanvasItem **board;
	GooCanvasItem *item, *text;
	int num, pos, newpos;
	int x, y;
	double dx = 0.0, dy = 0.0;
	int move;

	item = (GooCanvasItem*) GOO_CANVAS_GROUP_VIEW (view)->group;
	canvas = goo_canvas_item_view_get_canvas_view (view);
	board = g_object_get_data (G_OBJECT (canvas), "board");
	num = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "piece_num"));
	pos = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "piece_pos"));
	text = g_object_get_data (G_OBJECT (item), "text");

#if 0
	g_print ("In piece_event pos: %i,%i num: %i\n", pos % 4, pos / 4,
		 num + 1);
#endif

	y = pos / 4;
	x = pos % 4;

	move = TRUE;

	if ((y > 0) && (board[(y - 1) * 4 + x] == NULL)) {
	  dx = 0.0;
	  dy = -1.0;
	  y--;
	} else if ((y < 3) && (board[(y + 1) * 4 + x] == NULL)) {
	  dx = 0.0;
	  dy = 1.0;
	  y++;
	} else if ((x > 0) && (board[y * 4 + x - 1] == NULL)) {
	  dx = -1.0;
	  dy = 0.0;
	  x--;
	} else if ((x < 3) && (board[y * 4 + x + 1] == NULL)) {
	  dx = 1.0;
	  dy = 0.0;
	  x++;
	} else
	  move = FALSE;

	if (move) {
	  newpos = y * 4 + x;
	  board[pos] = NULL;
	  board[newpos] = item;
	  g_object_set_data (G_OBJECT (item), "piece_pos", GINT_TO_POINTER (newpos));
	  goo_canvas_item_translate (item, dx * PIECE_SIZE,
				     dy * PIECE_SIZE);
	  test_win (board);
	}

	return FALSE;
}


static void
on_item_view_created (GooCanvasView     *view,
		      GooCanvasItemView *item_view,
		      GooCanvasItem     *item,
		      gpointer           data)
{
  if (goo_canvas_item_get_parent (item) && GOO_IS_CANVAS_GROUP (item))
    {
      g_signal_connect (item_view, "enter_notify_event",
			(GtkSignalFunc) piece_enter_notify,
			NULL);
      g_signal_connect (item_view, "leave_notify_event",
			(GtkSignalFunc) piece_leave_notify,
			NULL);
      g_signal_connect (item_view, "button_press_event",
			(GtkSignalFunc) piece_button_press,
			NULL);
    }
}


#define SCRAMBLE_MOVES 256

static void
scramble (GtkObject *object, gpointer data)
{
	GooCanvasView *canvas;
	GooCanvasItem **board;
	int i;
	int pos, oldpos;
	int dir;
	int x, y;

	srand (time (NULL));

	canvas = data;
	board = g_object_get_data (G_OBJECT (canvas), "board");

	/* First, find the blank spot */

	for (pos = 0; pos < 16; pos++)
		if (board[pos] == NULL)
			break;

	/* "Move the blank spot" around in order to scramble the pieces */

	for (i = 0; i < SCRAMBLE_MOVES; i++) {
retry_scramble:
		dir = rand () % 4;

		x = y = 0;

		if ((dir == 0) && (pos > 3)) /* up */
			y = -1;
		else if ((dir == 1) && (pos < 12)) /* down */
			y = 1;
		else if ((dir == 2) && ((pos % 4) != 0)) /* left */
			x = -1;
		else if ((dir == 3) && ((pos % 4) != 3)) /* right */
			x = 1;
		else
			goto retry_scramble;

		oldpos = pos + y * 4 + x;
		board[pos] = board[oldpos];
		board[oldpos] = NULL;
		g_object_set_data (G_OBJECT (board[pos]), "piece_pos",
				   GINT_TO_POINTER (pos));

		goo_canvas_item_translate (board[pos], -x * PIECE_SIZE,
					   -y * PIECE_SIZE);
		pos = oldpos;
	}
}

GtkWidget *
create_canvas_fifteen (void)
{
	GtkWidget *vbox;
	GtkWidget *alignment;
	GtkWidget *frame;
	GtkWidget *canvas;
	GtkWidget *button;
	GooCanvasModelSimple *canvas_model;
	GooCanvasItem **board;
	GooCanvasItem *root, *rect, *text;
	int i, x, y;
	char buf[20];

	vbox = gtk_vbox_new (FALSE, 4);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
	gtk_widget_show (vbox);

	alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
	gtk_box_pack_start (GTK_BOX (vbox), alignment, TRUE, TRUE, 0);
	gtk_widget_show (alignment);

	frame = gtk_frame_new (NULL);
	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
	gtk_container_add (GTK_CONTAINER (alignment), frame);
	gtk_widget_show (frame);

	/* Create the canvas and board */

	canvas = goo_canvas_view_new ();

	g_signal_connect (canvas, "item_view_created",
			  (GtkSignalFunc) on_item_view_created,
			  NULL);

	canvas_model = goo_canvas_model_simple_new ();

	goo_canvas_view_set_model (GOO_CANVAS_VIEW (canvas),
				   GOO_CANVAS_MODEL (canvas_model));
	g_object_unref (canvas_model);

	root = goo_canvas_model_get_root_item (GOO_CANVAS_MODEL (canvas_model));
	gtk_widget_set_size_request (canvas,
				     PIECE_SIZE * 4 + 1, PIECE_SIZE * 4 + 1);
	goo_canvas_view_set_bounds (GOO_CANVAS_VIEW (canvas), 0, 0,
				    PIECE_SIZE * 4 + 1, PIECE_SIZE * 4 + 1);
	gtk_container_add (GTK_CONTAINER (frame), canvas);
	gtk_widget_show (canvas);

	board = g_new (GooCanvasItem *, 16);
	g_object_set_data (G_OBJECT (canvas), "board", board);
	g_signal_connect (canvas, "destroy",
			  (GtkSignalFunc) free_stuff,
			  board);

	for (i = 0; i < 15; i++) {
		y = i / 4;
		x = i % 4;

		board[i] = goo_canvas_group_new (root);
		goo_canvas_item_translate (board[i], x * PIECE_SIZE,
					   y * PIECE_SIZE);

		rect = goo_canvas_rect_new (board[i], 0, 0,
					    PIECE_SIZE, PIECE_SIZE,
					    "fill_color", get_piece_color (i),
					    "stroke_color", "black",
					    "line-width", 1.0,
					    NULL);

		sprintf (buf, "%d", i + 1);

		text = goo_canvas_item_new (board[i], GOO_TYPE_CANVAS_TEXT,
					    "text", buf,
					    "x", (double) PIECE_SIZE / 2.0,
					    "y", (double) PIECE_SIZE / 2.0,
					    "font", "Sans bold 24",
					    "anchor", GTK_ANCHOR_CENTER,
					    "fill_color", "black",
					    NULL);

		g_object_set_data (G_OBJECT (board[i]), "text", text);

		g_object_set_data (G_OBJECT (board[i]), "piece_num", GINT_TO_POINTER (i));
		g_object_set_data (G_OBJECT (board[i]), "piece_pos", GINT_TO_POINTER (i));

	}

	board[15] = NULL;

	/* Scramble button */

	button = gtk_button_new_with_label ("Scramble");
	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
	g_object_set_data (G_OBJECT (button), "board", board);
	g_signal_connect (button, "clicked",
			  (GtkSignalFunc) scramble,
			  canvas);
	gtk_widget_show (button);

	return vbox;
}

--- NEW FILE: demo-grabs.c ---
#include <config.h>
#include <string.h>
#include <gtk/gtk.h>
#include <goocanvas.h>


static gboolean
on_widget_expose (GtkWidget *widget,
		  GdkEventExpose *event,
		  char *item_id)
{
  g_print ("%s received 'expose' signal\n", item_id);

  gtk_paint_box (widget->style, widget->window, GTK_STATE_NORMAL,
		 GTK_SHADOW_IN, &event->area, widget, NULL, 0, 0,
		 widget->allocation.width, widget->allocation.height);

  return FALSE;
}


static gboolean
on_widget_enter_notify (GtkWidget *widget,
			GdkEventCrossing *event,
			char *item_id)
{
  g_print ("%s received 'enter-notify' signal\n", item_id);
  return TRUE;
}


static gboolean
on_widget_leave_notify (GtkWidget *widget,
			GdkEventCrossing *event,
			char *item_id)
{
  g_print ("%s received 'leave-notify' signal\n", item_id);
  return TRUE;
}


static gboolean
on_widget_motion_notify (GtkWidget *widget,
			 GdkEventMotion *event,
			 char *item_id)
{
  g_print ("%s received 'motion-notify' signal (window: %p)\n", item_id,
	   event->window);

  if (event->is_hint)
    gdk_window_get_pointer (event->window, NULL, NULL, NULL);

  return TRUE;
}


static gboolean
on_widget_button_press (GtkWidget *widget,
			GdkEventButton *event,
			char *item_id)
{
  g_print ("%s received 'button-press' signal\n", item_id);

  if (strstr (item_id, "explicit"))
    {
      GdkGrabStatus status;
      GdkEventMask mask = GDK_BUTTON_PRESS_MASK
	| GDK_BUTTON_RELEASE_MASK
	| GDK_POINTER_MOTION_MASK
	| GDK_POINTER_MOTION_HINT_MASK
	| GDK_ENTER_NOTIFY_MASK
	| GDK_LEAVE_NOTIFY_MASK;

      status = gdk_pointer_grab (widget->window, FALSE, mask, FALSE, NULL,
				 event->time);
      if (status == GDK_GRAB_SUCCESS)
	g_print ("grabbed pointer\n");
      else
	g_print ("pointer grab failed\n");
    }

  return TRUE;
}


static gboolean
on_widget_button_release (GtkWidget *widget,
			  GdkEventButton *event,
			  char *item_id)
{
  g_print ("%s received 'button-release' signal\n", item_id);

  if (strstr (item_id, "explicit"))
    {
      GdkDisplay *display;

      display = gtk_widget_get_display (widget);
      gdk_display_pointer_ungrab (display, event->time);
      g_print ("released pointer grab\n");
    }

  return TRUE;
}




static gboolean
on_enter_notify (GooCanvasItemView *view,
		 GooCanvasItemView *target,
		 GdkEventCrossing *event,
		 gpointer data)
{
  GooCanvasItem *item = goo_canvas_item_view_get_item (target);
  char *item_id = g_object_get_data (G_OBJECT (item), "id");

  g_print ("%s received 'enter-notify' signal\n", item_id);
  return FALSE;
}


static gboolean
on_leave_notify (GooCanvasItemView *view,
		 GooCanvasItemView *target,
		 GdkEventCrossing *event,
		 gpointer data)
{
  GooCanvasItem *item = goo_canvas_item_view_get_item (target);
  char *item_id = g_object_get_data (G_OBJECT (item), "id");

  g_print ("%s received 'leave-notify' signal\n", item_id);
  return FALSE;
}


static gboolean
on_motion_notify (GooCanvasItemView *view,
		  GooCanvasItemView *target,
		  GdkEventMotion *event,
		  gpointer data)
{
  GooCanvasItem *item = goo_canvas_item_view_get_item (target);
  char *item_id = g_object_get_data (G_OBJECT (item), "id");

  g_print ("%s received 'motion-notify' signal\n", item_id);
  return FALSE;
}


static gboolean
on_button_press (GooCanvasItemView *view,
		 GooCanvasItemView *target,
		 GdkEventButton *event,
		 gpointer data)
{
  GooCanvasItem *item = goo_canvas_item_view_get_item (target);
  char *item_id = g_object_get_data (G_OBJECT (item), "id");

  g_print ("%s received 'button-press' signal\n", item_id);

  if (strstr (item_id, "explicit"))
    {
      GooCanvasView *canvas_view;
      GdkGrabStatus status;
      GdkEventMask mask = GDK_BUTTON_PRESS_MASK
	| GDK_BUTTON_RELEASE_MASK
	| GDK_POINTER_MOTION_MASK
	| GDK_POINTER_MOTION_HINT_MASK
	| GDK_ENTER_NOTIFY_MASK
	| GDK_LEAVE_NOTIFY_MASK;

      canvas_view = goo_canvas_item_view_get_canvas_view (view);
      status = goo_canvas_view_pointer_grab (canvas_view, view, mask, NULL,
					     event->time);
      if (status == GDK_GRAB_SUCCESS)
	g_print ("grabbed pointer\n");
      else
	g_print ("pointer grab failed\n");
    }

  return FALSE;
}


static gboolean
on_button_release (GooCanvasItemView *view,
		   GooCanvasItemView *target,
		   GdkEventButton *event,
		   gpointer data)
{
  GooCanvasItem *item = goo_canvas_item_view_get_item (target);
  char *item_id = g_object_get_data (G_OBJECT (item), "id");

  g_print ("%s received 'button-release' signal\n", item_id);

  if (strstr (item_id, "explicit"))
    {
      GooCanvasView *canvas_view;

      canvas_view = goo_canvas_item_view_get_canvas_view (view);
      goo_canvas_view_pointer_ungrab (canvas_view, view, event->time);
      g_print ("released pointer grab\n");
    }

  return FALSE;
}


static void
create_fixed (GtkTable *table, gint row, gchar *text, gchar *id)
{
  GtkWidget *label, *fixed, *drawing_area;
  char *view_id;

  label = gtk_label_new (text);
  gtk_table_attach (table, label, 0, 1, row, row + 1,
		    0, 0, 0, 0);
  gtk_widget_show (label);

  fixed = gtk_fixed_new ();
  gtk_fixed_set_has_window (GTK_FIXED (fixed), TRUE);
  gtk_widget_set_events (fixed,
			 GDK_EXPOSURE_MASK
			 | GDK_BUTTON_PRESS_MASK
			 | GDK_BUTTON_RELEASE_MASK
			 | GDK_POINTER_MOTION_MASK
			 | GDK_POINTER_MOTION_HINT_MASK
			 | GDK_KEY_PRESS_MASK
			 | GDK_KEY_RELEASE_MASK
			 | GDK_ENTER_NOTIFY_MASK
			 | GDK_LEAVE_NOTIFY_MASK
			 | GDK_FOCUS_CHANGE_MASK);
  gtk_widget_set_size_request (fixed, 200, 100);
  gtk_table_attach (GTK_TABLE (table), fixed, 1, 2, row, row + 1,
		    0, 0, 0, 0);
  gtk_widget_show (fixed);

  view_id = g_strdup_printf ("%s-background", id);
  g_signal_connect (fixed, "expose_event",
		    (GtkSignalFunc) on_widget_expose, view_id);

  g_signal_connect (fixed, "enter_notify_event",
		    (GtkSignalFunc) on_widget_enter_notify, view_id);
  g_signal_connect (fixed, "leave_notify_event",
		    (GtkSignalFunc) on_widget_leave_notify, view_id);
  g_signal_connect (fixed, "motion_notify_event",
		    (GtkSignalFunc) on_widget_motion_notify, view_id);
  g_signal_connect (fixed, "button_press_event",
		    (GtkSignalFunc) on_widget_button_press, view_id);
  g_signal_connect (fixed, "button_release_event",
		    (GtkSignalFunc) on_widget_button_release, view_id);


  drawing_area = gtk_drawing_area_new ();
  gtk_widget_set_events (drawing_area,
			 GDK_EXPOSURE_MASK
			 | GDK_BUTTON_PRESS_MASK
			 | GDK_BUTTON_RELEASE_MASK
			 | GDK_POINTER_MOTION_MASK
			 | GDK_POINTER_MOTION_HINT_MASK
			 | GDK_KEY_PRESS_MASK
			 | GDK_KEY_RELEASE_MASK
			 | GDK_ENTER_NOTIFY_MASK
			 | GDK_LEAVE_NOTIFY_MASK
			 | GDK_FOCUS_CHANGE_MASK);
			 
  gtk_widget_set_size_request (drawing_area, 60, 60);
  gtk_fixed_put (GTK_FIXED (fixed), drawing_area, 20, 20);
  gtk_widget_show (drawing_area);

  view_id = g_strdup_printf ("%s-left", id);
  g_signal_connect (drawing_area, "expose_event",
		    (GtkSignalFunc) on_widget_expose, view_id);

  g_signal_connect (drawing_area, "enter_notify_event",
		    (GtkSignalFunc) on_widget_enter_notify, view_id);
  g_signal_connect (drawing_area, "leave_notify_event",
		    (GtkSignalFunc) on_widget_leave_notify, view_id);
  g_signal_connect (drawing_area, "motion_notify_event",
		    (GtkSignalFunc) on_widget_motion_notify, view_id);
  g_signal_connect (drawing_area, "button_press_event",
		    (GtkSignalFunc) on_widget_button_press, view_id);
  g_signal_connect (drawing_area, "button_release_event",
		    (GtkSignalFunc) on_widget_button_release, view_id);


  drawing_area = gtk_drawing_area_new ();
  gtk_widget_set_events (drawing_area,
			 GDK_EXPOSURE_MASK
			 | GDK_BUTTON_PRESS_MASK
			 | GDK_BUTTON_RELEASE_MASK
			 | GDK_POINTER_MOTION_MASK
			 | GDK_POINTER_MOTION_HINT_MASK
			 | GDK_KEY_PRESS_MASK
			 | GDK_KEY_RELEASE_MASK
			 | GDK_ENTER_NOTIFY_MASK
			 | GDK_LEAVE_NOTIFY_MASK
			 | GDK_FOCUS_CHANGE_MASK);
			 
  gtk_widget_set_size_request (drawing_area, 60, 60);
  gtk_fixed_put (GTK_FIXED (fixed), drawing_area, 120, 20);
  gtk_widget_show (drawing_area);

  view_id = g_strdup_printf ("%s-right", id);
  g_signal_connect (drawing_area, "expose_event",
		    (GtkSignalFunc) on_widget_expose, view_id);

  g_signal_connect (drawing_area, "enter_notify_event",
		    (GtkSignalFunc) on_widget_enter_notify, view_id);
  g_signal_connect (drawing_area, "leave_notify_event",
		    (GtkSignalFunc) on_widget_leave_notify, view_id);
  g_signal_connect (drawing_area, "motion_notify_event",
		    (GtkSignalFunc) on_widget_motion_notify, view_id);
  g_signal_connect (drawing_area, "button_press_event",
		    (GtkSignalFunc) on_widget_button_press, view_id);
  g_signal_connect (drawing_area, "button_release_event",
		    (GtkSignalFunc) on_widget_button_release, view_id);
}


static void
on_item_view_created (GooCanvasView     *view,
		      GooCanvasItemView *item_view,
		      GooCanvasItem     *item,
		      gpointer           data)
{
  if (GOO_IS_CANVAS_RECT (item))
    {
      g_signal_connect (item_view, "enter_notify_event",
			(GtkSignalFunc) on_enter_notify, NULL);
      g_signal_connect (item_view, "leave_notify_event",
			(GtkSignalFunc) on_leave_notify, NULL);
      g_signal_connect (item_view, "motion_notify_event",
			(GtkSignalFunc) on_motion_notify, NULL);
      g_signal_connect (item_view, "button_press_event",
			(GtkSignalFunc) on_button_press, NULL);
      g_signal_connect (item_view, "button_release_event",
			(GtkSignalFunc) on_button_release, NULL);
    }
}


static void
create_canvas (GtkTable *table, gint row, gchar *text, gchar *id)
{
  GtkWidget *label, *canvas;
  GooCanvasModelSimple *canvas_model;
  GooCanvasItem *root, *rect;
  char *view_id;

  label = gtk_label_new (text);
  gtk_table_attach (table, label, 0, 1, row, row + 1,
		    0, 0, 0, 0);
  gtk_widget_show (label);

  canvas = goo_canvas_view_new ();

  g_signal_connect (canvas, "item_view_created",
		    (GtkSignalFunc) on_item_view_created,
		    NULL);

  gtk_widget_set_size_request (canvas, 200, 100);
  goo_canvas_view_set_bounds (GOO_CANVAS_VIEW (canvas), 0, 0, 200, 100);
  gtk_table_attach (table, canvas, 1, 2, row, row + 1,
		    0, 0, 0, 0);
  gtk_widget_show (canvas);

  canvas_model = goo_canvas_model_simple_new ();
  goo_canvas_view_set_model (GOO_CANVAS_VIEW (canvas),
			     GOO_CANVAS_MODEL (canvas_model));
  g_object_unref (canvas_model);

  root = goo_canvas_model_get_root_item (GOO_CANVAS_MODEL (canvas_model));
  rect = goo_canvas_rect_new (root, 0, 0, 200, 100,
			      "stroke-pattern", NULL,
			      "fill-color", "yellow",
			      NULL);
  view_id = g_strdup_printf ("%s-yellow", id);
  g_object_set_data_full (G_OBJECT (rect), "id", view_id, g_free);

  rect = goo_canvas_rect_new (root, 20, 20, 60, 60,
			      "stroke-pattern", NULL,
			      "fill-color", "blue",
			      NULL);
  view_id = g_strdup_printf ("%s-blue", id);
  g_object_set_data_full (G_OBJECT (rect), "id", view_id, g_free);

  rect = goo_canvas_rect_new (root, 120, 20, 60, 60,
			      "stroke-pattern", NULL,
			      "fill-color", "red",
			      NULL);
  view_id = g_strdup_printf ("%s-red", id);
  g_object_set_data_full (G_OBJECT (rect), "id", view_id, g_free);
}


GtkWidget *
create_grabs_page (void)
{
  GtkWidget *table, *label;

  table = gtk_table_new (5, 2, FALSE);
  gtk_container_set_border_width (GTK_CONTAINER (table), 12);
  gtk_table_set_row_spacings (GTK_TABLE (table), 12);
  gtk_table_set_col_spacings (GTK_TABLE (table), 12);
  gtk_widget_show (table);

  label = gtk_label_new ("Move the mouse over the widgets and canvas items on the right to see what events they receive.\nClick buttons to start explicit or implicit pointer grabs and see what events they receive now.\n(They should all receive the same events.)");
  gtk_table_attach (GTK_TABLE (table), label, 0, 2, 0, 1, 0, 0, 0, 0);
  gtk_widget_show (label);

  /* Drawing area with explicit grabs. */
  create_fixed (GTK_TABLE (table), 1,
		"Widget with Explicit Grabs:",
		"widget-explicit");

  /* Drawing area with implicit grabs. */
  create_fixed (GTK_TABLE (table), 2,
		"Widget with Implicit Grabs:",
		"widget-implicit");

  /* Canvas with explicit grabs. */
  create_canvas (GTK_TABLE (table), 3,
		 "Canvas with Explicit Grabs:",
		 "canvas-explicit");

  /* Canvas with implicit grabs. */
  create_canvas (GTK_TABLE (table), 4,
		 "Canvas with Implicit Grabs:",
		 "canvas-implicit");

  return table;
}

--- NEW FILE: demo-paths.c ---
#include <config.h>
#include <string.h>
#include <gtk/gtk.h>
#include <goocanvas.h>


static void
create_paths (GooCanvasModelSimple   *canvas_model)
{
  GooCanvasItem *root, *path;

  root = goo_canvas_model_get_root_item (GOO_CANVAS_MODEL (canvas_model));

  /* Test the simple commands like moveto and lineto: MmZzLlHhVv. */
  path = goo_canvas_path_new (root, "M 20 20 L 40 40", NULL);
  path = goo_canvas_path_new (root, "M30 20 l20, 20", NULL);
  path = goo_canvas_path_new (root, "M 60 20 H 80", NULL);
  path = goo_canvas_path_new (root, "M60 40 h20", NULL);
  path = goo_canvas_path_new (root, "M 100,20 V 40", NULL);
  path = goo_canvas_path_new (root, "M 120 20 v 20", NULL);
  path = goo_canvas_path_new (root, "M 140 20 h20 v20 h-20 z", NULL);
  path = goo_canvas_path_new (root,
			      "M 180 20 h20 v20 h-20 z m 5,5 h10 v10 h-10 z",
			      "fill-color", "red",
			      "fill-rule", CAIRO_FILL_RULE_EVEN_ODD,
			      NULL);

  path = goo_canvas_path_new (root, "M 220 20 L 260 20 L 240 40 z",
			      "fill-color", "red",
			      "stroke-color", "blue",
			      "line-width", 3.0,
			      NULL);

  /* Test the bezier curve commands: CcSsQqTt. */
  path = goo_canvas_path_new (root,
			      "M20,100 C20,50 100,50 100,100 S180,150 180,100",
			      NULL);

  path = goo_canvas_path_new (root,
			      "M220,100 c0,-50 80,-50 80,0 s80,50 80,0",
			      NULL);

  path = goo_canvas_path_new (root,
			      "M20,200 Q60,130 100,200 T180,200",
			      NULL);

  path = goo_canvas_path_new (root,
			      "M220,200 q40,-70 80,0 t80,0",
			      NULL);

  /* Test the elliptical arc commands: Aa. */
  path = goo_canvas_path_new (root,
			      "M200,500 h-150 a150,150 0 1,0 150,-150 z",
			      "fill-color", "red",
			      "stroke-color", "blue",
			      "line-width", 5.0,
			      NULL);

  path = goo_canvas_path_new (root,
			      "M175,475 v-150 a150,150 0 0,0 -150,150 z",
			      "fill-color", "yellow",
			      "stroke-color", "blue",
			      "line-width", 5.0,
			      NULL);

  path = goo_canvas_path_new (root,
			      "M400,600 l 50,-25 "
			      "a25,25 -30 0,1 50,-25 l 50,-25 "
			      "a25,50 -30 0,1 50,-25 l 50,-25 "
			      "a25,75 -30 0,1 50,-25 l 50,-25 "
			      "a25,100 -30 0,1 50,-25 l 50,-25",
			      "stroke-color", "red",
			      "line-width", 5.0,
			      NULL);

  path = goo_canvas_path_new (root,
			      "M 525,75 a100,50 0 0,0 100,50",
			      "stroke-color", "red",
			      "line-width", 5.0,
			      NULL);
  path = goo_canvas_path_new (root,
			      "M 725,75 a100,50 0 0,1 100,50",
			      "stroke-color", "red",
			      "line-width", 5.0,
			      NULL);
  path = goo_canvas_path_new (root,
			      "M 525,200 a100,50 0 1,0 100,50",
			      "stroke-color", "red",
			      "line-width", 5.0,
			      NULL);
  path = goo_canvas_path_new (root,
			      "M 725,200 a100,50 0 1,1 100,50",
			      "stroke-color", "red",
			      "line-width", 5.0,
			      NULL);
}


GtkWidget *
create_paths_page (void)
{
  GtkWidget *vbox, *alignment, *frame, *label, *canvas, *scrolled_win;
  GooCanvasModelSimple *canvas_model;
  GtkAdjustment *hadj, *vadj;

  vbox = gtk_vbox_new (FALSE, 4);
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
  gtk_widget_show (vbox);

  /* Instructions */

  label = gtk_label_new ("Demo Paths");
  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
  /*gtk_widget_show (label);*/

  /* Frame and canvas */

  alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
  gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
  gtk_widget_show (alignment);

  frame = gtk_frame_new (NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
  gtk_container_add (GTK_CONTAINER (alignment), frame);
  gtk_widget_show (frame);

  canvas = goo_canvas_view_new ();

  canvas_model = goo_canvas_model_simple_new ();

  gtk_widget_set_size_request (canvas, 600, 450);
  goo_canvas_view_set_bounds (GOO_CANVAS_VIEW (canvas), 0, 0, 1000, 1000);
  gtk_widget_show (canvas);

  hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 1000, 10, 100, 100));
  vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 1000, 10, 100, 100));
  scrolled_win = gtk_scrolled_window_new (hadj, vadj);
  gtk_widget_show (scrolled_win);
  gtk_container_add (GTK_CONTAINER (frame), scrolled_win);

  gtk_container_add (GTK_CONTAINER (scrolled_win), canvas);

  create_paths (canvas_model);

  goo_canvas_view_set_model (GOO_CANVAS_VIEW (canvas),
			     GOO_CANVAS_MODEL (canvas_model));
  g_object_unref (canvas_model);

  return vbox;
}

--- NEW FILE: demo-scalability.c ---
#include <config.h>
#include <math.h>
#include <gtk/gtk.h>
#include <goocanvas.h>


#define N_COLS 5
#define N_ROWS 20
#define PADDING 10

#if 1
#define USE_PIXMAP 
#endif

GtkWidget *
create_canvas_scalability (void)
{
	GtkWidget *vbox;
	GtkWidget *frame;
	GtkWidget *scrolled_win, *canvas;
	GtkWidget *table;
	GdkPixbuf *pixbuf;
	GooCanvasModelSimple *canvas_model;
	GooCanvasItem *root, *item;
	int i, j, width, height;
	GtkAdjustment *hadj, *vadj;

	vbox = gtk_vbox_new (FALSE, 4);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
	gtk_widget_show (vbox);

	table = gtk_table_new (2, 2, FALSE);
	gtk_table_set_row_spacings (GTK_TABLE (table), 4);
	gtk_table_set_col_spacings (GTK_TABLE (table), 4);
	gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
	gtk_widget_show (table);
	
	frame = gtk_frame_new (NULL);
	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
	gtk_table_attach (GTK_TABLE (table), frame,
			  0, 1, 0, 1,
			  GTK_EXPAND | GTK_FILL | GTK_SHRINK,
			  GTK_EXPAND | GTK_FILL | GTK_SHRINK,
			  0, 0);
	gtk_widget_show (frame);

	/* Create the canvas and board */

	pixbuf = gdk_pixbuf_new_from_file("toroid.png", NULL);
#ifdef USE_PIXMAP
	width = gdk_pixbuf_get_width (pixbuf) + 3;
	height = gdk_pixbuf_get_height (pixbuf) +1;
#else
	width = 37;
	height = 19;
#endif
	
	canvas = goo_canvas_view_new ();
	canvas_model = goo_canvas_model_simple_new ();

	goo_canvas_view_set_model (GOO_CANVAS_VIEW (canvas),
				   GOO_CANVAS_MODEL (canvas_model));
	g_object_unref (canvas_model);

	root = goo_canvas_model_get_root_item (GOO_CANVAS_MODEL (canvas_model));

	gtk_widget_set_size_request (canvas, 600, 450);
	goo_canvas_view_set_bounds (GOO_CANVAS_VIEW (canvas), 0, 0,
				    N_COLS * (width + PADDING),
				    N_ROWS * (height + PADDING));
	gtk_widget_show (canvas);


	hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 1000, 10, 100, 100));
	vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 1000, 10, 100, 100));
	scrolled_win = gtk_scrolled_window_new (hadj, vadj);
	gtk_widget_show (scrolled_win);
	gtk_container_add (GTK_CONTAINER (frame), scrolled_win);

	gtk_container_add (GTK_CONTAINER (scrolled_win), canvas);


	for (i = 0; i < N_COLS; i++) {
		for (j = 0; j < N_ROWS; j++) {
#ifdef USE_PIXMAP
		  item = goo_canvas_item_new (root, GOO_TYPE_CANVAS_IMAGE,
					      "x", (double) i * (width + PADDING),
					      "y", (double) j * (height + PADDING),
					      "pixbuf", pixbuf,
					      NULL);
#else
		  item = goo_canvas_polyline_new_rect (root,
						       i * (width + PADDING),
						       j * (height + PADDING),
						       i * (width + PADDING) + width,
						       j * (height + PADDING) + height);
		  g_object_set (item,
				"fill_color", (j%2)?"mediumseagreen":"steelblue",
				NULL);
#endif
			
		}
	}

	return vbox;
}

--- NEW FILE: demo.c ---
/*
 * GooCanvas Demo. Copyright (C) 2005 Damon Chaplin.
 * Released under the GNU LGPL license. See COPYING for details.
 *
 * main.c - demo app.
 */
#include <config.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <cairo-pdf.h>
#include <goocanvas.h>

GooCanvasItem *ellipse2, *textitem;

gboolean dragging = FALSE;
double drag_x, drag_y;
[...1254 lines suppressed...]
int
main (int argc, char *argv[])
{
  GooCanvasModelSimple *canvas_model;
  GtkWidget *window;

  gtk_set_locale ();
  gtk_init (&argc, &argv);

  canvas_model = create_model ();

  /* Create 2 windows to show off multiple views. */
  window = create_window (canvas_model);
#if 1
  window = create_window (canvas_model);
#endif

  gtk_main ();
  return 0;
}

--- NEW FILE: flower.png ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: toroid.png ---
(This appears to be a binary file; contents omitted.)



More information about the cairo-commit mailing list