From c36b0c965970195bf6e67bed251469cb3c61b7e1 Mon Sep 17 00:00:00 2001 From: edgrif <edgrif> Date: Wed, 10 Mar 2010 14:59:47 +0000 Subject: [PATCH] replaced by new version --- foocanvas/foo-canvas-line.c | 1313 --------- foocanvas/foo-canvas-pixbuf.c | 860 ------ foocanvas/foo-canvas-polygon.c | 847 ------ foocanvas/foo-canvas-rect-ellipse.c | 1490 ---------- foocanvas/foo-canvas-text.c | 1623 ----------- foocanvas/foo-canvas-widget.c | 593 ---- foocanvas/foo-canvas.c | 4027 --------------------------- foocanvas/foo-canvas.h | 540 ---- 8 files changed, 11293 deletions(-) delete mode 100755 foocanvas/foo-canvas-line.c delete mode 100755 foocanvas/foo-canvas-pixbuf.c delete mode 100755 foocanvas/foo-canvas-polygon.c delete mode 100755 foocanvas/foo-canvas-rect-ellipse.c delete mode 100755 foocanvas/foo-canvas-text.c delete mode 100755 foocanvas/foo-canvas-widget.c delete mode 100755 foocanvas/foo-canvas.c delete mode 100755 foocanvas/foo-canvas.h diff --git a/foocanvas/foo-canvas-line.c b/foocanvas/foo-canvas-line.c deleted file mode 100755 index 012d98645..000000000 --- a/foocanvas/foo-canvas-line.c +++ /dev/null @@ -1,1313 +0,0 @@ -/* Last edited: May 11 10:57 2004 (rnc) */ -/* - * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation - * All rights reserved. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with the Gnome Library; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -/* - @NOTATION@ - */ - -/* Line/curve item type for FooCanvas widget - * - * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget. Tk is - * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties. - * - * - * Author: Federico Mena <federico@nuclecu.unam.mx> - */ - -#include <config.h> -#include <math.h> -#include <string.h> -#include "libfoocanvas.h" - -#define noVERBOSE - -#define DEFAULT_SPLINE_STEPS 12 /* this is what Tk uses */ -#define NUM_ARROW_POINTS 6 /* number of points in an arrowhead */ -#define NUM_STATIC_POINTS 256 /* number of static points to use to avoid allocating arrays */ - - -#define GROW_BOUNDS(bx1, by1, bx2, by2, x, y) { \ - if (x < bx1) \ - bx1 = x; \ - \ - if (x > bx2) \ - bx2 = x; \ - \ - if (y < by1) \ - by1 = y; \ - \ - if (y > by2) \ - by2 = y; \ -} - - -enum { - PROP_0, - PROP_POINTS, - PROP_FILL_COLOR, - PROP_FILL_COLOR_GDK, - PROP_FILL_COLOR_RGBA, - PROP_FILL_STIPPLE, - PROP_WIDTH_PIXELS, - PROP_WIDTH_UNITS, - PROP_CAP_STYLE, - PROP_JOIN_STYLE, - PROP_LINE_STYLE, - PROP_FIRST_ARROWHEAD, - PROP_LAST_ARROWHEAD, - PROP_SMOOTH, - PROP_SPLINE_STEPS, - PROP_ARROW_SHAPE_A, - PROP_ARROW_SHAPE_B, - PROP_ARROW_SHAPE_C -}; - - -static void foo_canvas_line_class_init (FooCanvasLineClass *class); -static void foo_canvas_line_init (FooCanvasLine *line); -static void foo_canvas_line_destroy (GtkObject *object); -static void foo_canvas_line_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec); -static void foo_canvas_line_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec); - -static void foo_canvas_line_update (FooCanvasItem *item, - double i2w_dx, double i2w_dy, - int flags); -static void foo_canvas_line_realize (FooCanvasItem *item); -static void foo_canvas_line_unrealize (FooCanvasItem *item); -static void foo_canvas_line_draw (FooCanvasItem *item, GdkDrawable *drawable, - GdkEventExpose *event); -static double foo_canvas_line_point (FooCanvasItem *item, double x, double y, - int cx, int cy, FooCanvasItem **actual_item); -static void foo_canvas_line_translate (FooCanvasItem *item, double dx, double dy); -static void foo_canvas_line_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2); - - -static FooCanvasItemClass *parent_class; - - -GtkType -foo_canvas_line_get_type (void) -{ - static GtkType line_type = 0; - - if (!line_type) { - /* FIXME: Convert to gobject style. */ - static const GtkTypeInfo line_info = { - (char *)"FooCanvasLine", - sizeof (FooCanvasLine), - sizeof (FooCanvasLineClass), - (GtkClassInitFunc) foo_canvas_line_class_init, - (GtkObjectInitFunc) foo_canvas_line_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - line_type = gtk_type_unique (foo_canvas_item_get_type (), &line_info); - } - - return line_type; -} - -static void -foo_canvas_line_class_init (FooCanvasLineClass *class) -{ - GObjectClass *gobject_class; - GtkObjectClass *object_class; - FooCanvasItemClass *item_class; - - gobject_class = (GObjectClass *) class; - object_class = (GtkObjectClass *) class; - item_class = (FooCanvasItemClass *) class; - - parent_class = gtk_type_class (foo_canvas_item_get_type ()); - - gobject_class->set_property = foo_canvas_line_set_property; - gobject_class->get_property = foo_canvas_line_get_property; - - g_object_class_install_property - (gobject_class, - PROP_POINTS, - g_param_spec_boxed ("points", NULL, NULL, - FOO_TYPE_CANVAS_POINTS, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FILL_COLOR, - g_param_spec_string ("fill_color", NULL, NULL, - NULL, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FILL_COLOR_GDK, - g_param_spec_boxed ("fill_color_gdk", NULL, NULL, - GDK_TYPE_COLOR, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FILL_COLOR_RGBA, - g_param_spec_uint ("fill_color_rgba", NULL, NULL, - 0, G_MAXUINT, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FILL_STIPPLE, - g_param_spec_object ("fill_stipple", NULL, NULL, - GDK_TYPE_DRAWABLE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_WIDTH_PIXELS, - g_param_spec_uint ("width_pixels", NULL, NULL, - 0, G_MAXUINT, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_WIDTH_UNITS, - g_param_spec_double ("width_units", NULL, NULL, - 0.0, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_CAP_STYLE, - g_param_spec_enum ("cap_style", NULL, NULL, - GDK_TYPE_CAP_STYLE, - GDK_CAP_BUTT, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_JOIN_STYLE, - g_param_spec_enum ("join_style", NULL, NULL, - GDK_TYPE_JOIN_STYLE, - GDK_JOIN_MITER, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_LINE_STYLE, - g_param_spec_enum ("line_style", NULL, NULL, - GDK_TYPE_LINE_STYLE, - GDK_LINE_SOLID, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FIRST_ARROWHEAD, - g_param_spec_boolean ("first_arrowhead", NULL, NULL, - FALSE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_LAST_ARROWHEAD, - g_param_spec_boolean ("last_arrowhead", NULL, NULL, - FALSE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_SMOOTH, - g_param_spec_boolean ("smooth", NULL, NULL, - FALSE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_SPLINE_STEPS, - g_param_spec_uint ("spline_steps", NULL, NULL, - 0, G_MAXUINT, DEFAULT_SPLINE_STEPS, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_ARROW_SHAPE_A, - g_param_spec_double ("arrow_shape_a", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_ARROW_SHAPE_B, - g_param_spec_double ("arrow_shape_b", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_ARROW_SHAPE_C, - g_param_spec_double ("arrow_shape_c", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - - object_class->destroy = foo_canvas_line_destroy; - - item_class->update = foo_canvas_line_update; - item_class->realize = foo_canvas_line_realize; - item_class->unrealize = foo_canvas_line_unrealize; - item_class->draw = foo_canvas_line_draw; - item_class->point = foo_canvas_line_point; - item_class->translate = foo_canvas_line_translate; - item_class->bounds = foo_canvas_line_bounds; -} - -static void -foo_canvas_line_init (FooCanvasLine *line) -{ - line->width = 0.0; - line->cap = GDK_CAP_BUTT; - line->join = GDK_JOIN_MITER; - line->line_style = GDK_LINE_SOLID; - line->shape_a = 0.0; - line->shape_b = 0.0; - line->shape_c = 0.0; - line->spline_steps = DEFAULT_SPLINE_STEPS; -} - -static void -foo_canvas_line_destroy (GtkObject *object) -{ - FooCanvasLine *line; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_LINE (object)); - - line = FOO_CANVAS_LINE (object); - - /* remember, destroy can be run multiple times! */ - - if (line->coords) - g_free (line->coords); - line->coords = NULL; - - if (line->first_coords) - g_free (line->first_coords); - line->first_coords = NULL; - - if (line->last_coords) - g_free (line->last_coords); - line->last_coords = NULL; - - if (line->stipple) - g_object_unref (line->stipple); - line->stipple = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -/* Computes the bounding box of the line, including its arrow points. Assumes that the number of - * points in the line is not zero. - */ -static void -get_bounds (FooCanvasLine *line, double *bx1, double *by1, double *bx2, double *by2) -{ - double *coords; - double x1, y1, x2, y2; - double width; - int i; - - if (!line->coords) { - *bx1 = *by1 = *bx2 = *by2 = 0.0; - return; - } - - /* Find bounding box of line's points */ - - x1 = x2 = line->coords[0]; - y1 = y2 = line->coords[1]; - - for (i = 1, coords = line->coords + 2; i < line->num_points; i++, coords += 2) - GROW_BOUNDS (x1, y1, x2, y2, coords[0], coords[1]); - - /* Add possible over-estimate for wide lines */ - - if (line->width_pixels) - width = line->width / line->item.canvas->pixels_per_unit_x; - else - width = line->width; - - x1 -= width; - y1 -= width; - x2 += width; - y2 += width; - - /* For mitered lines, make a second pass through all the points. Compute the location of - * the two miter vertex points and add them to the bounding box. - */ - - if (line->join == GDK_JOIN_MITER) - for (i = line->num_points, coords = line->coords; i >= 3; i--, coords += 2) { - double mx1, my1, mx2, my2; - - if (foo_canvas_get_miter_points (coords[0], coords[1], - coords[2], coords[3], - coords[4], coords[5], - width, - &mx1, &my1, &mx2, &my2)) { - GROW_BOUNDS (x1, y1, x2, y2, mx1, my1); - GROW_BOUNDS (x1, y1, x2, y2, mx2, my2); - } - } - - /* Add the arrow points, if any */ - - if (line->first_arrow && line->first_coords) - for (i = 0, coords = line->first_coords; i < NUM_ARROW_POINTS; i++, coords += 2) - GROW_BOUNDS (x1, y1, x2, y2, coords[0], coords[1]); - - if (line->last_arrow && line->last_coords) - for (i = 0, coords = line->last_coords; i < NUM_ARROW_POINTS; i++, coords += 2) - GROW_BOUNDS (x1, y1, x2, y2, coords[0], coords[1]); - - /* Done */ - - *bx1 = x1; - *by1 = y1; - *bx2 = x2; - *by2 = y2; -} - -/* Computes the bounding box of the line, in canvas coordinates. Assumes that the number of points in the polygon is - * not zero. - */ -static void -get_bounds_canvas (FooCanvasLine *line, - double *bx1, double *by1, double *bx2, double *by2, - double i2w_dx, double i2w_dy) -{ - FooCanvasItem *item; - double bbox_x0, bbox_y0, bbox_x1, bbox_y1; - - item = FOO_CANVAS_ITEM (line); - - get_bounds (line, &bbox_x0, &bbox_y0, &bbox_x1, &bbox_y1); - - bbox_x0 += i2w_dx; - bbox_y0 += i2w_dy; - bbox_x1 += i2w_dx; - bbox_y1 += i2w_dy; - - foo_canvas_w2c_rect_d (item->canvas, - &bbox_x0, &bbox_y0, &bbox_x1, &bbox_y1); - - /* include 1 pixel of fudge */ - *bx1 = bbox_x0 - 1; - *by1 = bbox_y0 - 1; - *bx2 = bbox_x1 + 1; - *by2 = bbox_y1 + 1; -} - -/* Recalculates the arrow polygons for the line */ -static void -reconfigure_arrows (FooCanvasLine *line) -{ - double *poly, *coords; - double dx, dy, length; - double sin_theta, cos_theta, tmp; - double frac_height; /* Line width as fraction of arrowhead width */ - double backup; /* Distance to backup end points so the line ends in the middle of the arrowhead */ - double vx, vy; /* Position of arrowhead vertex */ - double shape_a, shape_b, shape_c; - double width; - int i; - - if (line->num_points == 0) - return; - - /* Set up things */ - - if (line->first_arrow) { - if (line->first_coords) { - line->coords[0] = line->first_coords[0]; - line->coords[1] = line->first_coords[1]; - } else - line->first_coords = g_new (double, 2 * NUM_ARROW_POINTS); - } else if (line->first_coords) { - line->coords[0] = line->first_coords[0]; - line->coords[1] = line->first_coords[1]; - - g_free (line->first_coords); - line->first_coords = NULL; - } - - i = 2 * (line->num_points - 1); - - if (line->last_arrow) { - if (line->last_coords) { - line->coords[i] = line->last_coords[0]; - line->coords[i + 1] = line->last_coords[1]; - } else - line->last_coords = g_new (double, 2 * NUM_ARROW_POINTS); - } else if (line->last_coords) { - line->coords[i] = line->last_coords[0]; - line->coords[i + 1] = line->last_coords[1]; - - g_free (line->last_coords); - line->last_coords = NULL; - } - - if (!line->first_arrow && !line->last_arrow) - return; - - if (line->width_pixels) - width = line->width / line->item.canvas->pixels_per_unit_x; - else - width = line->width; - - /* Add fudge value for better-looking results */ - - shape_a = line->shape_a; - shape_b = line->shape_b; - shape_c = line->shape_c + width / 2.0; - - if (line->width_pixels) { - shape_a /= line->item.canvas->pixels_per_unit_x; - shape_b /= line->item.canvas->pixels_per_unit_x; - shape_c /= line->item.canvas->pixels_per_unit_x; - } - - shape_a += 0.001; - shape_b += 0.001; - shape_c += 0.001; - - /* Compute the polygon for the first arrowhead and adjust the first point in the line so - * that the line does not stick out past the leading edge of the arrowhead. - */ - - frac_height = (line->width / 2.0) / shape_c; - backup = frac_height * shape_b + shape_a * (1.0 - frac_height) / 2.0; - - if (line->first_arrow) { - poly = line->first_coords; - poly[0] = poly[10] = line->coords[0]; - poly[1] = poly[11] = line->coords[1]; - - dx = poly[0] - line->coords[2]; - dy = poly[1] - line->coords[3]; - length = sqrt (dx * dx + dy * dy); - if (length < FOO_CANVAS_EPSILON) - sin_theta = cos_theta = 0.0; - else { - sin_theta = dy / length; - cos_theta = dx / length; - } - - vx = poly[0] - shape_a * cos_theta; - vy = poly[1] - shape_a * sin_theta; - - tmp = shape_c * sin_theta; - - poly[2] = poly[0] - shape_b * cos_theta + tmp; - poly[8] = poly[2] - 2.0 * tmp; - - tmp = shape_c * cos_theta; - - poly[3] = poly[1] - shape_b * sin_theta - tmp; - poly[9] = poly[3] + 2.0 * tmp; - - poly[4] = poly[2] * frac_height + vx * (1.0 - frac_height); - poly[5] = poly[3] * frac_height + vy * (1.0 - frac_height); - poly[6] = poly[8] * frac_height + vx * (1.0 - frac_height); - poly[7] = poly[9] * frac_height + vy * (1.0 - frac_height); - - /* Move the first point towards the second so that the corners at the end of the - * line are inside the arrowhead. - */ - - line->coords[0] = poly[0] - backup * cos_theta; - line->coords[1] = poly[1] - backup * sin_theta; - } - - /* Same process for last arrowhead */ - - if (line->last_arrow) { - coords = line->coords + 2 * (line->num_points - 2); - poly = line->last_coords; - poly[0] = poly[10] = coords[2]; - poly[1] = poly[11] = coords[3]; - - dx = poly[0] - coords[0]; - dy = poly[1] - coords[1]; - length = sqrt (dx * dx + dy * dy); - if (length < FOO_CANVAS_EPSILON) - sin_theta = cos_theta = 0.0; - else { - sin_theta = dy / length; - cos_theta = dx / length; - } - - vx = poly[0] - shape_a * cos_theta; - vy = poly[1] - shape_a * sin_theta; - - tmp = shape_c * sin_theta; - - poly[2] = poly[0] - shape_b * cos_theta + tmp; - poly[8] = poly[2] - 2.0 * tmp; - - tmp = shape_c * cos_theta; - - poly[3] = poly[1] - shape_b * sin_theta - tmp; - poly[9] = poly[3] + 2.0 * tmp; - - poly[4] = poly[2] * frac_height + vx * (1.0 - frac_height); - poly[5] = poly[3] * frac_height + vy * (1.0 - frac_height); - poly[6] = poly[8] * frac_height + vx * (1.0 - frac_height); - poly[7] = poly[9] * frac_height + vy * (1.0 - frac_height); - - coords[2] = poly[0] - backup * cos_theta; - coords[3] = poly[1] - backup * sin_theta; - } -} - -/* Convenience function to set the line's GC's foreground color */ -static void -set_line_gc_foreground (FooCanvasLine *line) -{ - GdkColor c; - - if (!line->gc) - return; - - c.pixel = line->fill_pixel; - gdk_gc_set_foreground (line->gc, &c); -} - -/* Recalculate the line's width and set it in its GC */ -static void -set_line_gc_width (FooCanvasLine *line) -{ - int width; - - if (!line->gc) - return; - - if (line->width_pixels) - width = (int) line->width; - else - width = (int) (line->width * line->item.canvas->pixels_per_unit_x + 0.5); - - gdk_gc_set_line_attributes (line->gc, - width, - line->line_style, - (line->first_arrow || line->last_arrow) ? GDK_CAP_BUTT : line->cap, - line->join); -} - -/* Sets the stipple pattern for the line */ -static void -set_stipple (FooCanvasLine *line, GdkBitmap *stipple, int reconfigure) -{ - if (line->stipple && !reconfigure) - g_object_unref (line->stipple); - - line->stipple = stipple; - if (stipple && !reconfigure) - g_object_ref (stipple); - - if (line->gc) { - if (stipple) { - gdk_gc_set_stipple (line->gc, stipple); - gdk_gc_set_fill (line->gc, GDK_STIPPLED); - } else - gdk_gc_set_fill (line->gc, GDK_SOLID); - } -} - -static void -foo_canvas_line_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) -{ - FooCanvasItem *item; - FooCanvasLine *line; - FooCanvasPoints *points; - GdkColor color = { 0, 0, 0, 0, }; - GdkColor *pcolor; - gboolean color_changed; - int have_pixel; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_LINE (object)); - - item = FOO_CANVAS_ITEM (object); - line = FOO_CANVAS_LINE (object); - - color_changed = FALSE; - have_pixel = FALSE; - - switch (param_id) { - case PROP_POINTS: - points = g_value_get_boxed (value); - - if (line->coords) { - g_free (line->coords); - line->coords = NULL; - } - - if (!points) - line->num_points = 0; - else { - line->num_points = points->num_points; - line->coords = g_new (double, 2 * line->num_points); - memcpy (line->coords, points->coords, 2 * line->num_points * sizeof (double)); - } - - /* Drop the arrowhead polygons if they exist -- they will be regenerated */ - - if (line->first_coords) { - g_free (line->first_coords); - line->first_coords = NULL; - } - - if (line->last_coords) { - g_free (line->last_coords); - line->last_coords = NULL; - } - - /* Since the line's points have changed, we need to re-generate arrowheads in - * addition to recalculating the bounds. - */ - foo_canvas_item_request_update (item); - break; - - case PROP_FILL_COLOR: - if (g_value_get_string (value)) - gdk_color_parse (g_value_get_string (value), &color); - line->fill_rgba = ((color.red & 0xff00) << 16 | - (color.green & 0xff00) << 8 | - (color.blue & 0xff00) | - 0xff); - color_changed = TRUE; - break; - - case PROP_FILL_COLOR_GDK: - pcolor = g_value_get_boxed (value); - if (pcolor) { - GdkColormap *colormap; - color = *pcolor; - - colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); - gdk_rgb_find_color (colormap, &color); - - have_pixel = TRUE; - } - - line->fill_rgba = ((color.red & 0xff00) << 16 | - (color.green & 0xff00) << 8 | - (color.blue & 0xff00) | - 0xff); - color_changed = TRUE; - break; - - case PROP_FILL_COLOR_RGBA: - line->fill_rgba = g_value_get_uint (value); - color_changed = TRUE; - break; - - case PROP_FILL_STIPPLE: - set_stipple (line, (GdkBitmap *) g_value_get_object (value), FALSE); - foo_canvas_item_request_redraw (item); - break; - - case PROP_WIDTH_PIXELS: - line->width = g_value_get_uint (value); - line->width_pixels = TRUE; - set_line_gc_width (line); - foo_canvas_item_request_update (item); - break; - - case PROP_WIDTH_UNITS: - line->width = fabs (g_value_get_double (value)); - line->width_pixels = FALSE; - set_line_gc_width (line); - foo_canvas_item_request_update (item); - break; - - case PROP_CAP_STYLE: - line->cap = g_value_get_enum (value); - foo_canvas_item_request_update (item); - break; - - case PROP_JOIN_STYLE: - line->join = g_value_get_enum (value); - foo_canvas_item_request_update (item); - break; - - case PROP_LINE_STYLE: - line->line_style = g_value_get_enum (value); - set_line_gc_width (line); - foo_canvas_item_request_update (item); - break; - - case PROP_FIRST_ARROWHEAD: - line->first_arrow = g_value_get_boolean (value); - foo_canvas_item_request_update (item); - break; - - case PROP_LAST_ARROWHEAD: - line->last_arrow = g_value_get_boolean (value); - foo_canvas_item_request_update (item); - break; - - case PROP_SMOOTH: - /* FIXME */ - break; - - case PROP_SPLINE_STEPS: - /* FIXME */ - break; - - case PROP_ARROW_SHAPE_A: - line->shape_a = fabs (g_value_get_double (value)); - foo_canvas_item_request_update (item); - break; - - case PROP_ARROW_SHAPE_B: - line->shape_b = fabs (g_value_get_double (value)); - foo_canvas_item_request_update (item); - break; - - case PROP_ARROW_SHAPE_C: - line->shape_c = fabs (g_value_get_double (value)); - foo_canvas_item_request_update (item); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } - - if (color_changed) { - if (have_pixel) - line->fill_pixel = color.pixel; - else - line->fill_pixel = foo_canvas_get_color_pixel (item->canvas, - line->fill_rgba); - - set_line_gc_foreground (line); - - foo_canvas_item_request_redraw (item); - } -} - -/* Returns a copy of the line's points without the endpoint adjustments for - * arrowheads. - */ -static FooCanvasPoints * -get_points (FooCanvasLine *line) -{ - FooCanvasPoints *points; - int start_ofs, end_ofs; - - if (line->num_points == 0) - return NULL; - - start_ofs = end_ofs = 0; - - points = foo_canvas_points_new (line->num_points); - - /* Invariant: if first_coords or last_coords exist, then the line's - * endpoints have been adjusted. - */ - - if (line->first_coords) { - start_ofs = 1; - - points->coords[0] = line->first_coords[0]; - points->coords[1] = line->first_coords[1]; - } - - if (line->last_coords) { - end_ofs = 1; - - points->coords[2 * (line->num_points - 1)] = line->last_coords[0]; - points->coords[2 * (line->num_points - 1) + 1] = line->last_coords[1]; - } - - memcpy (points->coords + 2 * start_ofs, - line->coords + 2 * start_ofs, - 2 * (line->num_points - (start_ofs + end_ofs)) * sizeof (double)); - - return points; -} - -static void -foo_canvas_line_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec) -{ - FooCanvasLine *line; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_LINE (object)); - - line = FOO_CANVAS_LINE (object); - - switch (param_id) { - case PROP_POINTS: - g_value_set_boxed (value, get_points (line)); - break; - - case PROP_FILL_COLOR: - //g_value_take_string (value, - // g_strdup_printf ("#%02x%02x%02x", - // line->fill_rgba >> 24, - // (line->fill_rgba >> 16) & 0xff, - // (line->fill_rgba >> 8) & 0xff)); - break; - - case PROP_FILL_COLOR_GDK: { - FooCanvas *canvas = FOO_CANVAS_ITEM (line)->canvas; - GdkColormap *colormap = gtk_widget_get_colormap (GTK_WIDGET (canvas)); - GdkColor color; - - gdk_colormap_query_color (colormap, line->fill_pixel, &color); - g_value_set_boxed (value, &color); - break; - } - - case PROP_FILL_COLOR_RGBA: - g_value_set_uint (value, line->fill_rgba); - break; - - case PROP_FILL_STIPPLE: - g_value_set_object (value, line->stipple); - break; - - case PROP_WIDTH_PIXELS: - g_value_set_uint (value, line->width); - break; - - case PROP_WIDTH_UNITS: - g_value_set_double (value, line->width); - break; - - case PROP_CAP_STYLE: - g_value_set_enum (value, line->cap); - break; - - case PROP_JOIN_STYLE: - g_value_set_enum (value, line->join); - break; - - case PROP_LINE_STYLE: - g_value_set_enum (value, line->line_style); - break; - - case PROP_FIRST_ARROWHEAD: - g_value_set_boolean (value, line->first_arrow); - break; - - case PROP_LAST_ARROWHEAD: - g_value_set_boolean (value, line->last_arrow); - break; - - case PROP_SMOOTH: - g_value_set_boolean (value, line->smooth); - break; - - case PROP_SPLINE_STEPS: - g_value_set_uint (value, line->spline_steps); - break; - - case PROP_ARROW_SHAPE_A: - g_value_set_double (value, line->shape_a); - break; - - case PROP_ARROW_SHAPE_B: - g_value_set_double (value, line->shape_b); - break; - - case PROP_ARROW_SHAPE_C: - g_value_set_double (value, line->shape_c); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -static void -foo_canvas_line_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags) -{ - FooCanvasLine *line; - double x1, y1, x2, y2; - - line = FOO_CANVAS_LINE (item); - - if (parent_class->update) - (* parent_class->update) (item, i2w_dx, i2w_dy, flags); - - reconfigure_arrows (line); - - set_line_gc_foreground (line); - set_line_gc_width (line); - set_stipple (line, line->stipple, TRUE); - - get_bounds_canvas (line, &x1, &y1, &x2, &y2, i2w_dx, i2w_dy); - foo_canvas_update_bbox (item, x1, y1, x2, y2); -} - -static void -foo_canvas_line_realize (FooCanvasItem *item) -{ - FooCanvasLine *line; - - line = FOO_CANVAS_LINE (item); - - if (parent_class->realize) - (* parent_class->realize) (item); - - line->gc = gdk_gc_new (item->canvas->layout.bin_window); -#warning "FIXME: Need to recalc pixel values, set colours, etc." - -#if 0 - (* FOO_CANVAS_ITEM_CLASS (item->object.klass)->update) (item, NULL, NULL, 0); -#endif -} - -static void -foo_canvas_line_unrealize (FooCanvasItem *item) -{ - FooCanvasLine *line; - - line = FOO_CANVAS_LINE (item); - - g_object_unref (line->gc); - line->gc = NULL; - - if (parent_class->unrealize) - (* parent_class->unrealize) (item); -} - -static void -item_to_canvas (FooCanvas *canvas, double *item_coords, GdkPoint *canvas_coords, int num_points, - int *num_drawn_points, double i2w_dx, double i2w_dy) -{ - int i; - int old_cx, old_cy; - int cx, cy; - - /* the first point is always drawn */ - foo_canvas_w2c (canvas, - item_coords[0] + i2w_dx, - item_coords[1] + i2w_dy, - &canvas_coords->x, &canvas_coords->y); - old_cx = canvas_coords->x; - old_cy = canvas_coords->y; - canvas_coords++; - *num_drawn_points = 1; - - for (i = 1; i < num_points; i++) { - foo_canvas_w2c (canvas, - item_coords[i*2] + i2w_dx, - item_coords[i*2+1] + i2w_dy, - &cx, &cy); - if (old_cx != cx || old_cy != cy) { - canvas_coords->x = cx; - canvas_coords->y = cy; - old_cx = cx; - old_cy = cy; - canvas_coords++; - (*num_drawn_points)++; - } - } -} - -static void -foo_canvas_line_draw (FooCanvasItem *item, GdkDrawable *drawable, - GdkEventExpose *event) -{ - FooCanvasLine *line; - GdkPoint static_points[NUM_STATIC_POINTS]; - GdkPoint *points; - int actual_num_points_drawn; - double i2w_dx, i2w_dy; - - line = FOO_CANVAS_LINE (item); - - if (line->num_points == 0) - return; - - /* Build array of canvas pixel coordinates */ - - if (line->num_points <= NUM_STATIC_POINTS) - points = static_points; - else - points = g_new (GdkPoint, line->num_points); - - i2w_dx = 0.0; - i2w_dy = 0.0; - foo_canvas_item_i2w (item, &i2w_dx, &i2w_dy); - - item_to_canvas (item->canvas, line->coords, points, line->num_points, - &actual_num_points_drawn, i2w_dx, i2w_dy); - - if (line->stipple) - foo_canvas_set_stipple_origin (item->canvas, line->gc); - - gdk_draw_lines (drawable, line->gc, points, actual_num_points_drawn); - - if (points != static_points) - g_free (points); - - /* Draw arrowheads */ - - points = static_points; - - if (line->first_arrow) { - item_to_canvas (item->canvas, line->first_coords, points, NUM_ARROW_POINTS, - &actual_num_points_drawn, i2w_dx, i2w_dy); - gdk_draw_polygon (drawable, line->gc, TRUE, points, actual_num_points_drawn ); - } - - if (line->last_arrow) { - item_to_canvas (item->canvas, line->last_coords, points, NUM_ARROW_POINTS, - &actual_num_points_drawn, i2w_dx, i2w_dy); - gdk_draw_polygon (drawable, line->gc, TRUE, points, actual_num_points_drawn ); - } -} - -static double -foo_canvas_line_point (FooCanvasItem *item, double x, double y, - int cx, int cy, FooCanvasItem **actual_item) -{ - FooCanvasLine *line; - double *line_points = NULL, *coords; - double static_points[2 * NUM_STATIC_POINTS]; - double poly[10]; - double best, dist; - double dx, dy; - double width; - int num_points = 0, i; - int changed_miter_to_bevel; - -#ifdef VERBOSE - g_print ("foo_canvas_line_point x, y = (%g, %g); cx, cy = (%d, %d)\n", x, y, cx, cy); -#endif - - line = FOO_CANVAS_LINE (item); - - *actual_item = item; - - best = 1.0e36; - - /* Handle smoothed lines by generating an expanded set ot points */ - - if (line->smooth && (line->num_points > 2)) { - /* FIXME */ - } else { - num_points = line->num_points; - line_points = line->coords; - } - - /* Compute a polygon for each edge of the line and test the point against it. The effective - * width of the line is adjusted so that it will be at least one pixel thick (so that zero - * pixel-wide lines can be pickedup as well). - */ - - if (line->width_pixels) - width = line->width / item->canvas->pixels_per_unit_x; - else - width = line->width; - - if (width < (1.0 / item->canvas->pixels_per_unit_x)) - width = 1.0 / item->canvas->pixels_per_unit_x; - - changed_miter_to_bevel = 0; - - for (i = num_points, coords = line_points; i >= 2; i--, coords += 2) { - /* If rounding is done around the first point, then compute distance between the - * point and the first point. - */ - - if (((line->cap == GDK_CAP_ROUND) && (i == num_points)) - || ((line->join == GDK_JOIN_ROUND) && (i != num_points))) { - dx = coords[0] - x; - dy = coords[1] - y; - dist = sqrt (dx * dx + dy * dy) - width / 2.0; - if (dist < FOO_CANVAS_EPSILON) { - best = 0.0; - goto done; - } else if (dist < best) - best = dist; - } - - /* Compute the polygonal shape corresponding to this edge, with two points for the - * first point of the edge and two points for the last point of the edge. - */ - - if (i == num_points) - foo_canvas_get_butt_points (coords[2], coords[3], coords[0], coords[1], - width, (line->cap == GDK_CAP_PROJECTING), - poly, poly + 1, poly + 2, poly + 3); - else if ((line->join == GDK_JOIN_MITER) && !changed_miter_to_bevel) { - poly[0] = poly[6]; - poly[1] = poly[7]; - poly[2] = poly[4]; - poly[3] = poly[5]; - } else { - foo_canvas_get_butt_points (coords[2], coords[3], coords[0], coords[1], - width, FALSE, - poly, poly + 1, poly + 2, poly + 3); - - /* If this line uses beveled joints, then check the distance to a polygon - * comprising the last two points of the previous polygon and the first two - * from this polygon; this checks the wedges that fill the mitered point. - */ - - if ((line->join == GDK_JOIN_BEVEL) || changed_miter_to_bevel) { - poly[8] = poly[0]; - poly[9] = poly[1]; - - dist = foo_canvas_polygon_to_point (poly, 5, x, y); - if (dist < FOO_CANVAS_EPSILON) { - best = 0.0; - goto done; - } else if (dist < best) - best = dist; - - changed_miter_to_bevel = FALSE; - } - } - - if (i == 2) - foo_canvas_get_butt_points (coords[0], coords[1], coords[2], coords[3], - width, (line->cap == GDK_CAP_PROJECTING), - poly + 4, poly + 5, poly + 6, poly + 7); - else if (line->join == GDK_JOIN_MITER) { - if (!foo_canvas_get_miter_points (coords[0], coords[1], - coords[2], coords[3], - coords[4], coords[5], - width, - poly + 4, poly + 5, poly + 6, poly + 7)) { - changed_miter_to_bevel = TRUE; - foo_canvas_get_butt_points (coords[0], coords[1], coords[2], coords[3], - width, FALSE, - poly + 4, poly + 5, poly + 6, poly + 7); - } - } else - foo_canvas_get_butt_points (coords[0], coords[1], coords[2], coords[3], - width, FALSE, - poly + 4, poly + 5, poly + 6, poly + 7); - - poly[8] = poly[0]; - poly[9] = poly[1]; - - dist = foo_canvas_polygon_to_point (poly, 5, x, y); - if (dist < FOO_CANVAS_EPSILON) { - best = 0.0; - goto done; - } else if (dist < best) - best = dist; - } - - /* If caps are rounded, check the distance to the cap around the final end point of the line */ - - if (line->cap == GDK_CAP_ROUND) { - dx = coords[0] - x; - dy = coords[1] - y; - dist = sqrt (dx * dx + dy * dy) - width / 2.0; - if (dist < FOO_CANVAS_EPSILON) { - best = 0.0; - goto done; - } else - best = dist; - } - - /* sometimes the FooCanvasItem::update signal will not have - been processed between deleting the arrow points and a call - to this routine -- this can cause a segfault here */ - if ((line->first_arrow && !line->first_coords) || - (line->last_arrow && !line->last_coords)) - reconfigure_arrows(line); - - /* If there are arrowheads, check the distance to them */ - - if (line->first_arrow) { - dist = foo_canvas_polygon_to_point (line->first_coords, NUM_ARROW_POINTS, x, y); - if (dist < FOO_CANVAS_EPSILON) { - best = 0.0; - goto done; - } else - best = dist; - } - - if (line->last_arrow) { - dist = foo_canvas_polygon_to_point (line->last_coords, NUM_ARROW_POINTS, x, y); - if (dist < FOO_CANVAS_EPSILON) { - best = 0.0; - goto done; - } else - best = dist; - } - -done: - - if ((line_points != static_points) && (line_points != line->coords)) - g_free (line_points); - - return best; -} - -static void -foo_canvas_line_translate (FooCanvasItem *item, double dx, double dy) -{ - FooCanvasLine *line; - int i; - double *coords; - - line = FOO_CANVAS_LINE (item); - - for (i = 0, coords = line->coords; i < line->num_points; i++, coords += 2) { - coords[0] += dx; - coords[1] += dy; - } - - if (line->first_arrow) - for (i = 0, coords = line->first_coords; i < NUM_ARROW_POINTS; i++, coords += 2) { - coords[0] += dx; - coords[1] += dy; - } - - if (line->last_arrow) - for (i = 0, coords = line->last_coords; i < NUM_ARROW_POINTS; i++, coords += 2) { - coords[0] += dx; - coords[1] += dy; - } -} - -static void -foo_canvas_line_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2) -{ - FooCanvasLine *line; - - line = FOO_CANVAS_LINE (item); - - if (line->num_points == 0) { - *x1 = *y1 = *x2 = *y2 = 0.0; - return; - } - - get_bounds (line, x1, y1, x2, y2); -} diff --git a/foocanvas/foo-canvas-pixbuf.c b/foocanvas/foo-canvas-pixbuf.c deleted file mode 100755 index 348378078..000000000 --- a/foocanvas/foo-canvas-pixbuf.c +++ /dev/null @@ -1,860 +0,0 @@ -/* Last edited: May 11 11:33 2004 (rnc) */ -/* GNOME libraries - GdkPixbuf item for the GNOME canvas - * - * Copyright (C) 1999 The Free Software Foundation - * - * Author: Federico Mena-Quintero <federico@gimp.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <math.h> -#include <libfoocanvas/foo-canvas.h> -#include <libfoocanvas/foo-canvas-util.h> -#include <gdk-pixbuf/gdk-pixbuf.h> -#include "foo-canvas-pixbuf.h" - -/* Private part of the FooCanvasPixbuf structure */ -typedef struct { - /* Our gdk-pixbuf */ - GdkPixbuf *pixbuf, *pixbuf_scaled; - - /* Width value */ - double width; - - /* Height value */ - double height; - - /* X translation */ - double x; - - /* Y translation */ - double y; - - /* Whether dimensions are set and whether they are in pixels or units */ - guint width_set : 1; - guint width_in_pixels : 1; - guint height_set : 1; - guint height_in_pixels : 1; - guint x_in_pixels : 1; - guint y_in_pixels : 1; - - /* Whether the pixbuf has changed */ - guint need_pixbuf_update : 1; - - /* Whether the transformation or size have changed */ - guint need_xform_update : 1; - - /* Should the point method ignore transparent areas */ - guint point_ignores_alpha : 1; - - /* Anchor */ - GtkAnchorType anchor; - - /* Approximation method used for transformations */ - GdkInterpType interp_type; - -} PixbufPrivate; - -/* Object argument IDs */ -enum { - PROP_0, - PROP_PIXBUF, - PROP_WIDTH, - PROP_WIDTH_SET, - PROP_WIDTH_IN_PIXELS, - PROP_HEIGHT, - PROP_HEIGHT_SET, - PROP_HEIGHT_IN_PIXELS, - PROP_X, - PROP_X_IN_PIXELS, - PROP_Y, - PROP_Y_IN_PIXELS, - PROP_ANCHOR, - PROP_INTERP_TYPE, - PROP_POINT_IGNORES_ALPHA -}; - -static void foo_canvas_pixbuf_class_init (FooCanvasPixbufClass *class); -static void foo_canvas_pixbuf_init (FooCanvasPixbuf *cpb); -static void foo_canvas_pixbuf_destroy (GtkObject *object); -static void foo_canvas_pixbuf_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec); -static void foo_canvas_pixbuf_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec); - -static void foo_canvas_pixbuf_update (FooCanvasItem *item, - double i2w_dx, double i2w_dy, - int flags); -static void foo_canvas_pixbuf_draw (FooCanvasItem *item, GdkDrawable *drawable, - GdkEventExpose *expose); -static double foo_canvas_pixbuf_point (FooCanvasItem *item, double x, double y, int cx, int cy, - FooCanvasItem **actual_item); -static void foo_canvas_pixbuf_translate (FooCanvasItem *item, double dx, double dy); -static void foo_canvas_pixbuf_bounds (FooCanvasItem *item, - double *x1, double *y1, double *x2, double *y2); - -static FooCanvasItemClass *parent_class; - - - -/** - * foo_canvas_pixbuf_get_type: - * @void: - * - * Registers the #FooCanvasPixbuf class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #FooCanvasPixbuf class. - **/ -GtkType -foo_canvas_pixbuf_get_type (void) -{ - static GtkType canvas_pixbuf_type = 0; - - if (!canvas_pixbuf_type) { - /* FIXME: Convert to gobject style. */ - static const GtkTypeInfo canvas_pixbuf_info = { - (char *)"FooCanvasPixbuf", - sizeof (FooCanvasPixbuf), - sizeof (FooCanvasPixbufClass), - (GtkClassInitFunc) foo_canvas_pixbuf_class_init, - (GtkObjectInitFunc) foo_canvas_pixbuf_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - canvas_pixbuf_type = gtk_type_unique (foo_canvas_item_get_type (), - &canvas_pixbuf_info); - } - - return canvas_pixbuf_type; -} - -/* Class initialization function for the pixbuf canvas item */ -static void -foo_canvas_pixbuf_class_init (FooCanvasPixbufClass *class) -{ - GObjectClass *gobject_class; - GtkObjectClass *object_class; - FooCanvasItemClass *item_class; - - gobject_class = (GObjectClass *) class; - object_class = (GtkObjectClass *) class; - item_class = (FooCanvasItemClass *) class; - - parent_class = gtk_type_class (foo_canvas_item_get_type ()); - - gobject_class->set_property = foo_canvas_pixbuf_set_property; - gobject_class->get_property = foo_canvas_pixbuf_get_property; - - g_object_class_install_property - (gobject_class, - PROP_PIXBUF, - g_param_spec_object ("pixbuf", NULL, NULL, - GDK_TYPE_PIXBUF, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_WIDTH, - g_param_spec_double ("width", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_WIDTH_SET, - g_param_spec_boolean ("width_set", NULL, NULL, - FALSE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_WIDTH_IN_PIXELS, - g_param_spec_boolean ("width_in_pixels", NULL, NULL, - FALSE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_HEIGHT, - g_param_spec_double ("height", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_HEIGHT_SET, - g_param_spec_boolean ("height_set", NULL, NULL, - FALSE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_HEIGHT_IN_PIXELS, - g_param_spec_boolean ("height_in_pixels", NULL, NULL, - FALSE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_X, - g_param_spec_double ("x", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_X_IN_PIXELS, - g_param_spec_boolean ("x_in_pixels", NULL, NULL, - FALSE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_Y, - g_param_spec_double ("y", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_Y_IN_PIXELS, - g_param_spec_boolean ("y_in_pixels", NULL, NULL, - FALSE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_ANCHOR, - g_param_spec_enum ("anchor", NULL, NULL, - GTK_TYPE_ANCHOR_TYPE, - GTK_ANCHOR_NW, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_INTERP_TYPE, - g_param_spec_enum ("interp_type", NULL, NULL, - GDK_TYPE_INTERP_TYPE, - GDK_INTERP_BILINEAR, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_POINT_IGNORES_ALPHA, - g_param_spec_boolean ("point_ignores_alpha", NULL, NULL, - FALSE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - - object_class->destroy = foo_canvas_pixbuf_destroy; - - item_class->update = foo_canvas_pixbuf_update; - item_class->draw = foo_canvas_pixbuf_draw; - item_class->point = foo_canvas_pixbuf_point; - item_class->translate = foo_canvas_pixbuf_translate; - item_class->bounds = foo_canvas_pixbuf_bounds; -} - -/* Object initialization function for the pixbuf canvas item */ -static void -foo_canvas_pixbuf_init (FooCanvasPixbuf *gcp) -{ - PixbufPrivate *priv; - - priv = g_new0 (PixbufPrivate, 1); - gcp->priv = priv; - - priv->width = 0.0; - priv->height = 0.0; - priv->x = 0.0; - priv->y = 0.0; - priv->anchor = GTK_ANCHOR_NW; - priv->interp_type = GDK_INTERP_BILINEAR; - priv->point_ignores_alpha = FALSE; -} - -/* Destroy handler for the pixbuf canvas item */ -static void -foo_canvas_pixbuf_destroy (GtkObject *object) -{ - FooCanvasItem *item; - FooCanvasPixbuf *gcp; - PixbufPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_PIXBUF (object)); - - item = FOO_CANVAS_ITEM (object); - gcp = (FOO_CANVAS_PIXBUF (object)); - priv = gcp->priv; - - /* remember, destroy can be run multiple times! */ - - if (priv) { - foo_canvas_item_request_redraw (item); - - if (priv->pixbuf) - g_object_unref (priv->pixbuf); - if (priv->pixbuf_scaled) - g_object_unref (priv->pixbuf_scaled); - - g_free (priv); - gcp->priv = NULL; - } - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* Set_property handler for the pixbuf canvas item */ -static void -foo_canvas_pixbuf_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) -{ - FooCanvasItem *item; - FooCanvasPixbuf *gcp; - PixbufPrivate *priv; - GdkPixbuf *pixbuf; - double val; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_PIXBUF (object)); - - item = FOO_CANVAS_ITEM (object); - gcp = FOO_CANVAS_PIXBUF (object); - priv = gcp->priv; - - switch (param_id) { - case PROP_PIXBUF: - if (g_value_get_object (value)) - pixbuf = GDK_PIXBUF (g_value_get_object (value)); - else - pixbuf = NULL; - if (pixbuf != priv->pixbuf) { - if (pixbuf) { - g_return_if_fail - (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB); - g_return_if_fail - (gdk_pixbuf_get_n_channels (pixbuf) == 3 - || gdk_pixbuf_get_n_channels (pixbuf) == 4); - g_return_if_fail - (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8); - - g_object_ref (pixbuf); - } - - if (priv->pixbuf) - g_object_unref (priv->pixbuf); - priv->pixbuf = pixbuf; - - if (priv->pixbuf_scaled) { - g_object_unref (priv->pixbuf_scaled); - priv->pixbuf_scaled = NULL; - } - } - - priv->need_pixbuf_update = TRUE; - foo_canvas_item_request_update (item); - break; - - case PROP_WIDTH: - val = g_value_get_double (value); - g_return_if_fail (val >= 0.0); - priv->width = val; - priv->need_xform_update = TRUE; - foo_canvas_item_request_update (item); - break; - - case PROP_WIDTH_SET: - priv->width_set = g_value_get_boolean (value); - priv->need_xform_update = TRUE; - foo_canvas_item_request_update (item); - break; - - case PROP_WIDTH_IN_PIXELS: - priv->width_in_pixels = g_value_get_boolean (value); - priv->need_xform_update = TRUE; - foo_canvas_item_request_update (item); - break; - - case PROP_HEIGHT: - val = g_value_get_double (value); - g_return_if_fail (val >= 0.0); - priv->height = val; - priv->need_xform_update = TRUE; - foo_canvas_item_request_update (item); - break; - - case PROP_HEIGHT_SET: - priv->height_set = g_value_get_boolean (value); - priv->need_xform_update = TRUE; - foo_canvas_item_request_update (item); - break; - - case PROP_HEIGHT_IN_PIXELS: - priv->height_in_pixels = g_value_get_boolean (value); - priv->need_xform_update = TRUE; - foo_canvas_item_request_update (item); - break; - - case PROP_X: - priv->x = g_value_get_double (value); - priv->need_xform_update = TRUE; - foo_canvas_item_request_update (item); - break; - - case PROP_X_IN_PIXELS: - priv->x_in_pixels = g_value_get_boolean (value); - priv->need_xform_update = TRUE; - foo_canvas_item_request_update (item); - break; - - case PROP_Y: - priv->y = g_value_get_double (value); - priv->need_xform_update = TRUE; - foo_canvas_item_request_update (item); - break; - - case PROP_Y_IN_PIXELS: - priv->y_in_pixels = g_value_get_boolean (value); - priv->need_xform_update = TRUE; - foo_canvas_item_request_update (item); - break; - - case PROP_ANCHOR: - priv->anchor = g_value_get_enum (value); - priv->need_xform_update = TRUE; - foo_canvas_item_request_update (item); - break; - - case PROP_INTERP_TYPE: - priv->interp_type = g_value_get_enum (value); - priv->need_xform_update = TRUE; - foo_canvas_item_request_update (item); - break; - - case PROP_POINT_IGNORES_ALPHA: - priv->point_ignores_alpha = g_value_get_boolean (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -/* Get_property handler for the pixbuf canvasi item */ -static void -foo_canvas_pixbuf_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec) -{ - FooCanvasPixbuf *gcp; - PixbufPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_PIXBUF (object)); - - gcp = FOO_CANVAS_PIXBUF (object); - priv = gcp->priv; - - switch (param_id) { - case PROP_PIXBUF: - g_value_set_object (value, G_OBJECT (priv->pixbuf)); - break; - - case PROP_WIDTH: - g_value_set_double (value, priv->width); - break; - - case PROP_WIDTH_SET: - g_value_set_boolean (value, priv->width_set); - break; - - case PROP_WIDTH_IN_PIXELS: - g_value_set_boolean (value, priv->width_in_pixels); - break; - - case PROP_HEIGHT: - g_value_set_double (value, priv->height); - break; - - case PROP_HEIGHT_SET: - g_value_set_boolean (value, priv->height_set); - break; - - case PROP_HEIGHT_IN_PIXELS: - g_value_set_boolean (value, priv->height_in_pixels); - break; - - case PROP_X: - g_value_set_double (value, priv->x); - break; - - case PROP_X_IN_PIXELS: - g_value_set_boolean (value, priv->x_in_pixels); - break; - - case PROP_Y: - g_value_set_double (value, priv->y); - break; - - case PROP_Y_IN_PIXELS: - g_value_set_boolean (value, priv->y_in_pixels); - break; - - case PROP_ANCHOR: - g_value_set_enum (value, priv->anchor); - break; - - case PROP_INTERP_TYPE: - g_value_set_enum (value, priv->interp_type); - break; - - case PROP_POINT_IGNORES_ALPHA: - g_value_set_boolean (value, priv->point_ignores_alpha); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - - - -/* Bounds and utilities */ - - -/* Recomputes the bounding box of a pixbuf canvas item. The horizontal and - * vertical dimensions may be specified in units or pixels, separately, so we - * have to compute the components individually for each dimension. - * - * Returns the coordinates with respect to the parent items coordinates. - */ -static void -compute_bounding_box (FooCanvasPixbuf *gcp, - double i2w_dx, double i2w_dy, - double *bbox_x0, double *bbox_y0, - double *bbox_x1, double *bbox_y1) -{ - FooCanvasItem *item; - PixbufPrivate *priv; - double x, y; - double width, height; - - item = FOO_CANVAS_ITEM (gcp); - priv = gcp->priv; - - if (!priv->pixbuf) { - *bbox_x0 = *bbox_y0 = *bbox_x1 = *bbox_y1 = 0.0; - return; - } - - if (priv->x_in_pixels) { - x = i2w_dx + priv->x / item->canvas->pixels_per_unit_x; - } else { - x = i2w_dx + priv->x; - } - - if (priv->y_in_pixels) { - y = i2w_dy + priv->y / item->canvas->pixels_per_unit_y; - } else { - y = i2w_dy + priv->y; - } - - if (priv->width_set) { - width = priv->width; - } else { - width = gdk_pixbuf_get_width (priv->pixbuf); - } - - if (priv->width_in_pixels) - width /= item->canvas->pixels_per_unit_x; - - if (priv->height_set) { - height = priv->height; - } else { - height = gdk_pixbuf_get_height (priv->pixbuf); - } - - if (priv->height_in_pixels) - height /= item->canvas->pixels_per_unit_y; - - - switch (priv->anchor) { - case GTK_ANCHOR_NW: - case GTK_ANCHOR_W: - case GTK_ANCHOR_SW: - break; - - case GTK_ANCHOR_N: - case GTK_ANCHOR_CENTER: - case GTK_ANCHOR_S: - x -= width / 2.0; - break; - - case GTK_ANCHOR_NE: - case GTK_ANCHOR_E: - case GTK_ANCHOR_SE: - x -= width; - break; - - default: - break; - } - - switch (priv->anchor) { - case GTK_ANCHOR_NW: - case GTK_ANCHOR_N: - case GTK_ANCHOR_NE: - break; - - case GTK_ANCHOR_W: - case GTK_ANCHOR_CENTER: - case GTK_ANCHOR_E: - y -= height / 2.0; - break; - - case GTK_ANCHOR_SW: - case GTK_ANCHOR_S: - case GTK_ANCHOR_SE: - y -= height; - break; - - default: - break; - } - - *bbox_x0 = x; - *bbox_y0 = y; - *bbox_x1 = x + width; - *bbox_y1 = y + height; -} - - - -/* Update sequence */ - -/* Update handler for the pixbuf canvas item */ -static void -foo_canvas_pixbuf_update (FooCanvasItem *item, - double i2w_dx, double i2w_dy, - int flags) -{ - FooCanvasPixbuf *gcp; - PixbufPrivate *priv; - double bbox_x0, bbox_y0, bbox_x1, bbox_y1; - int w, h; - - gcp = FOO_CANVAS_PIXBUF (item); - priv = gcp->priv; - - if (parent_class->update) - (* parent_class->update) (item, i2w_dx, i2w_dy, flags); - - /* If we need a pixbuf update, or if the item changed visibility to - * shown, recompute the bounding box. - */ - if (priv->need_pixbuf_update || priv->need_xform_update || - (flags & FOO_CANVAS_UPDATE_DEEP)) { - - foo_canvas_item_request_redraw (item); - - compute_bounding_box (gcp, i2w_dx, i2w_dy, - &bbox_x0, &bbox_y0, - &bbox_x1, &bbox_y1); - - foo_canvas_w2c_d (item->canvas, - bbox_x0, bbox_y0, - &item->x1, &item->y1); - - foo_canvas_w2c_d (item->canvas, - bbox_x1, bbox_y1, - &item->x2, &item->y2); - - item->x1 = floor (item->x1); - item->y1 = floor (item->y1); - item->x2 = ceil (item->x2); - item->y2 = ceil (item->y2); - -#ifdef FOO_CANVAS_PIXBUF_VERBOSE - g_print ("BBox is %g %g %g %g\n", item->x1, item->y1, item->x2, item->y2); -#endif - - if (priv->pixbuf) { - w = item->x2 - item->x1; - h = item->y2 - item->y1; - - if (priv->pixbuf_scaled) - g_object_unref (priv->pixbuf_scaled); - if (gdk_pixbuf_get_width (priv->pixbuf) != w || - gdk_pixbuf_get_height (priv->pixbuf) != h) - priv->pixbuf_scaled = gdk_pixbuf_scale_simple ( - priv->pixbuf, w, h, priv->interp_type); - else - priv->pixbuf_scaled = g_object_ref (priv->pixbuf); - } - - foo_canvas_item_request_redraw (item); - - priv->need_pixbuf_update = FALSE; - priv->need_xform_update = FALSE; - } -} - - - -/* Draw handler for the pixbuf canvas item */ -static void -foo_canvas_pixbuf_draw (FooCanvasItem *item, GdkDrawable *drawable, - GdkEventExpose *expose) -{ - FooCanvasPixbuf *gcp; - PixbufPrivate *priv; - GdkRectangle display_rect, draw_rect; - GdkRegion *draw_region; - int w, h; - - gcp = FOO_CANVAS_PIXBUF (item); - priv = gcp->priv; - - if (!priv->pixbuf) - return; - - /* Compute the area we need to repaint */ - - w = item->x2 - item->x1; - h = item->y2 - item->y1; - - display_rect.x = item->x1; - display_rect.y = item->y1; - display_rect.width = w; - display_rect.height = h; - draw_region = gdk_region_rectangle (&display_rect); - gdk_region_intersect (draw_region, expose->region); - if (!gdk_region_empty (draw_region)) { - gdk_region_get_clipbox (draw_region, &draw_rect); - gdk_draw_pixbuf (drawable, NULL, priv->pixbuf_scaled, - /* pixbuf 0, 0 is at pix_rect.x, pix_rect.y */ - draw_rect.x - display_rect.x, - draw_rect.y - display_rect.y, - draw_rect.x, - draw_rect.y, - draw_rect.width, - draw_rect.height, - GDK_RGB_DITHER_NORMAL, 0, 0); - } - gdk_region_destroy (draw_region); -} - - - - -/* Point handler for the pixbuf canvas item */ -static double -foo_canvas_pixbuf_point (FooCanvasItem *item, double x, double y, int cx, int cy, - FooCanvasItem **actual_item) -{ - FooCanvasPixbuf *gcp; - PixbufPrivate *priv; - double x1, y1, x2, y2; - int px, py; - double no_hit; - guchar *src; - GdkPixbuf *pixbuf; - - gcp = FOO_CANVAS_PIXBUF (item); - priv = gcp->priv; - pixbuf = priv->pixbuf; - - *actual_item = item; - /* guessing that the x factor is OK here. RNGC */ - no_hit = item->canvas->pixels_per_unit_x * 2 + 10; - - if (!priv->pixbuf) - return no_hit; - - compute_bounding_box (gcp, 0.0, 0.0, - &x1, &y1, &x2, &y2); - - - if (x < x1 || x >= x2 || - y < y1 || y >= y2) - return no_hit; - - if (!gdk_pixbuf_get_has_alpha (pixbuf) || priv->point_ignores_alpha) - return 0.0; - - px = (x - x1) * gdk_pixbuf_get_width (pixbuf) / (x2 - x1); - py = (y - y1) * gdk_pixbuf_get_height (pixbuf) / (y2 - y1); - - src = gdk_pixbuf_get_pixels (pixbuf) + - py * gdk_pixbuf_get_rowstride (pixbuf) + - px * gdk_pixbuf_get_n_channels (pixbuf); - - if (src[3] < 128) - return no_hit; - else - return 0.0; -} - - - -static void -foo_canvas_pixbuf_translate (FooCanvasItem *item, double dx, double dy) -{ - FooCanvasPixbuf *gcp; - PixbufPrivate *priv; - - gcp = FOO_CANVAS_PIXBUF (item); - priv = gcp->priv; - - if (priv->x_in_pixels) { - priv->x += dx * item->canvas->pixels_per_unit_x; - } else { - priv->x += dx; - } - - if (priv->y_in_pixels) { - priv->y += dy * item->canvas->pixels_per_unit_y; - } else { - priv->y += dy; - } - - priv->need_xform_update = TRUE; -} - - - -/* Bounds handler for the pixbuf canvas item */ -static void -foo_canvas_pixbuf_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2) -{ - FooCanvasPixbuf *gcp; - PixbufPrivate *priv; - - gcp = FOO_CANVAS_PIXBUF (item); - priv = gcp->priv; - - if (!priv->pixbuf) { - *x1 = *y1 = *x2 = *y2 = 0.0; - return; - } - - compute_bounding_box (gcp, 0.0, 0.0, - x1, y1, x2, y2); -} diff --git a/foocanvas/foo-canvas-polygon.c b/foocanvas/foo-canvas-polygon.c deleted file mode 100755 index d9e6d7a9b..000000000 --- a/foocanvas/foo-canvas-polygon.c +++ /dev/null @@ -1,847 +0,0 @@ -/* Last edited: Jan 4 10:58 2006 (rds) */ -/* - * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation - * All rights reserved. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with the Gnome Library; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -/* - @NOTATION@ - */ -/* Polygon item type for FooCanvas widget - * - * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget. Tk is - * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties. - * - * Author: Federico Mena <federico@nuclecu.unam.mx> - */ - -#include <config.h> -#include <math.h> -#include <string.h> -#include "libfoocanvas.h" - - -#define NUM_STATIC_POINTS 256 /* Number of static points to use to avoid allocating arrays */ - - -#define GROW_BOUNDS(bx1, by1, bx2, by2, x, y) { \ - if (x < bx1) \ - bx1 = x; \ - \ - if (x > bx2) \ - bx2 = x; \ - \ - if (y < by1) \ - by1 = y; \ - \ - if (y > by2) \ - by2 = y; \ -} - - -enum { - PROP_0, - PROP_POINTS, - PROP_FILL_COLOR, - PROP_FILL_COLOR_GDK, - PROP_FILL_COLOR_RGBA, - PROP_OUTLINE_COLOR, - PROP_OUTLINE_COLOR_GDK, - PROP_OUTLINE_COLOR_RGBA, - PROP_FILL_STIPPLE, - PROP_OUTLINE_STIPPLE, - PROP_WIDTH_PIXELS, - PROP_WIDTH_UNITS -}; - - -static void foo_canvas_polygon_class_init (FooCanvasPolygonClass *class); -static void foo_canvas_polygon_init (FooCanvasPolygon *poly); -static void foo_canvas_polygon_destroy (GtkObject *object); -static void foo_canvas_polygon_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec); -static void foo_canvas_polygon_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec); - -static void foo_canvas_polygon_update (FooCanvasItem *item, - double i2w_dx, double i2w_dy, - int flags); -static void foo_canvas_polygon_realize (FooCanvasItem *item); -static void foo_canvas_polygon_unrealize (FooCanvasItem *item); -static void foo_canvas_polygon_draw (FooCanvasItem *item, GdkDrawable *drawable, - GdkEventExpose *expose); -static double foo_canvas_polygon_point (FooCanvasItem *item, double x, double y, - int cx, int cy, FooCanvasItem **actual_item); -static void foo_canvas_polygon_translate (FooCanvasItem *item, double dx, double dy); -static void foo_canvas_polygon_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2); - - -static FooCanvasItemClass *parent_class; - - -GtkType -foo_canvas_polygon_get_type (void) -{ - static GtkType polygon_type = 0; - - if (!polygon_type) { - /* FIXME: Convert to gobject style. */ - static const GtkTypeInfo polygon_info = { - (char *)"FooCanvasPolygon", - sizeof (FooCanvasPolygon), - sizeof (FooCanvasPolygonClass), - (GtkClassInitFunc) foo_canvas_polygon_class_init, - (GtkObjectInitFunc) foo_canvas_polygon_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - polygon_type = gtk_type_unique (foo_canvas_item_get_type (), &polygon_info); - } - - return polygon_type; -} - -static void -foo_canvas_polygon_class_init (FooCanvasPolygonClass *class) -{ - GObjectClass *gobject_class; - GtkObjectClass *object_class; - FooCanvasItemClass *item_class; - - gobject_class = (GObjectClass *) class; - object_class = (GtkObjectClass *) class; - item_class = (FooCanvasItemClass *) class; - - parent_class = gtk_type_class (foo_canvas_item_get_type ()); - - gobject_class->set_property = foo_canvas_polygon_set_property; - gobject_class->get_property = foo_canvas_polygon_get_property; - - g_object_class_install_property - (gobject_class, - PROP_POINTS, - g_param_spec_boxed ("points", NULL, NULL, - FOO_TYPE_CANVAS_POINTS, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FILL_COLOR, - g_param_spec_string ("fill_color", NULL, NULL, - NULL, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FILL_COLOR_GDK, - g_param_spec_boxed ("fill_color_gdk", NULL, NULL, - GDK_TYPE_COLOR, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FILL_COLOR_RGBA, - g_param_spec_uint ("fill_color_rgba", NULL, NULL, - 0, G_MAXUINT, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_OUTLINE_COLOR, - g_param_spec_string ("outline_color", NULL, NULL, - NULL, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_OUTLINE_COLOR_GDK, - g_param_spec_boxed ("outline_color_gdk", NULL, NULL, - GDK_TYPE_COLOR, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_OUTLINE_COLOR_RGBA, - g_param_spec_uint ("outline_color_rgba", NULL, NULL, - 0, G_MAXUINT, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FILL_STIPPLE, - g_param_spec_object ("fill_stipple", NULL, NULL, - GDK_TYPE_DRAWABLE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_OUTLINE_STIPPLE, - g_param_spec_object ("outline_stipple", NULL, NULL, - GDK_TYPE_DRAWABLE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_WIDTH_PIXELS, - g_param_spec_uint ("width_pixels", NULL, NULL, - 0, G_MAXUINT, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_WIDTH_UNITS, - g_param_spec_double ("width_units", NULL, NULL, - 0.0, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - - object_class->destroy = foo_canvas_polygon_destroy; - - item_class->update = foo_canvas_polygon_update; - item_class->realize = foo_canvas_polygon_realize; - item_class->unrealize = foo_canvas_polygon_unrealize; - item_class->draw = foo_canvas_polygon_draw; - item_class->point = foo_canvas_polygon_point; - item_class->translate = foo_canvas_polygon_translate; - item_class->bounds = foo_canvas_polygon_bounds; -} - -static void -foo_canvas_polygon_init (FooCanvasPolygon *poly) -{ - poly->width = 0.0; -} - -static void -foo_canvas_polygon_destroy (GtkObject *object) -{ - FooCanvasPolygon *poly; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_POLYGON (object)); - - poly = FOO_CANVAS_POLYGON (object); - - /* remember, destroy can be run multiple times! */ - - if (poly->coords) - g_free (poly->coords); - poly->coords = NULL; - - if (poly->fill_stipple) - g_object_unref (poly->fill_stipple); - poly->fill_stipple = NULL; - - if (poly->outline_stipple) - g_object_unref (poly->outline_stipple); - poly->outline_stipple = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -/* Computes the bounding box of the polygon. Assumes that the number of points in the polygon is - * not zero. - */ -static gboolean -get_bounds (FooCanvasPolygon *poly, double *bx1, double *by1, double *bx2, double *by2) -{ - double *coords; - double x1, y1, x2, y2; - double width; - int i; - - if (poly->num_points == 0) - return FALSE; - - /* Compute bounds of vertices */ - - x1 = x2 = poly->coords[0]; - y1 = y2 = poly->coords[1]; - - for (i = 1, coords = poly->coords + 2; i < poly->num_points; i++, coords += 2) { - GROW_BOUNDS (x1, y1, x2, y2, coords[0], coords[1]); - } - - /* Add outline width */ - - if (poly->width_pixels) - width = poly->width / poly->item.canvas->pixels_per_unit_x; - else - width = poly->width; - - width /= 2.0; - - x1 -= width; - y1 -= width; - x2 += width; - y2 += width; - - /* Done */ - - *bx1 = x1; - *by1 = y1; - *bx2 = x2; - *by2 = y2; - return TRUE; -} - -/* Computes the bounding box of the polygon, in canvas coordinates. Assumes that the number of points in the polygon is - * not zero. - */ -static gboolean -get_bounds_canvas (FooCanvasPolygon *poly, - double *bx1, double *by1, double *bx2, double *by2, - double i2w_dx, double i2w_dy) -{ - FooCanvasItem *item; - double bbox_x0, bbox_y0, bbox_x1, bbox_y1; - - item = FOO_CANVAS_ITEM (poly); - - if(!get_bounds (poly, &bbox_x0, &bbox_y0, &bbox_x1, &bbox_y1)) - return FALSE; - - bbox_x0 += i2w_dx; - bbox_y0 += i2w_dy; - bbox_x1 += i2w_dx; - bbox_y1 += i2w_dy; - - foo_canvas_w2c_rect_d (item->canvas, - &bbox_x0, &bbox_y0, &bbox_x1, &bbox_y1); - - /* include 1 pixel of fudge */ - *bx1 = bbox_x0 - 1; - *by1 = bbox_y0 - 1; - *bx2 = bbox_x1 + 1; - *by2 = bbox_y1 + 1; - return TRUE; -} - -/* Sets the points of the polygon item to the specified ones. If needed, it will add a point to - * close the polygon. - */ -static void -set_points (FooCanvasPolygon *poly, FooCanvasPoints *points) -{ - int duplicate; - - /* See if we need to duplicate the first point */ - - duplicate = ((points->coords[0] != points->coords[2 * points->num_points - 2]) - || (points->coords[1] != points->coords[2 * points->num_points - 1])); - - if (duplicate) - poly->num_points = points->num_points + 1; - else - poly->num_points = points->num_points; - - poly->coords = g_new (double, 2 * poly->num_points); - memcpy (poly->coords, points->coords, 2 * points->num_points * sizeof (double)); - - if (duplicate) { - poly->coords[2 * poly->num_points - 2] = poly->coords[0]; - poly->coords[2 * poly->num_points - 1] = poly->coords[1]; - } -} - -/* Convenience function to set a GC's foreground color to the specified pixel value */ -static void -set_gc_foreground (GdkGC *gc, gulong pixel) -{ - GdkColor c; - - if (!gc) - return; - - c.pixel = pixel; - gdk_gc_set_foreground (gc, &c); -} - -/* Sets the stipple pattern for the specified gc */ -static void -set_stipple (GdkGC *gc, GdkBitmap **internal_stipple, GdkBitmap *stipple, int reconfigure) -{ - if (*internal_stipple && !reconfigure) - g_object_unref (*internal_stipple); - - *internal_stipple = stipple; - if (stipple && !reconfigure) - g_object_ref (stipple); - - if (gc) { - if (stipple) { - gdk_gc_set_stipple (gc, stipple); - gdk_gc_set_fill (gc, GDK_STIPPLED); - } else - gdk_gc_set_fill (gc, GDK_SOLID); - } -} - -/* Recalculate the outline width of the polygon and set it in its GC */ -static void -set_outline_gc_width (FooCanvasPolygon *poly) -{ - int width; - - if (!poly->outline_gc) - return; - - if (poly->width_pixels) - width = (int) poly->width; - else - width = (int) (poly->width * poly->item.canvas->pixels_per_unit_x + 0.5); - - gdk_gc_set_line_attributes (poly->outline_gc, width, - GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); -} - -static void -foo_canvas_polygon_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) -{ - FooCanvasItem *item; - FooCanvasPolygon *poly; - FooCanvasPoints *points; - GdkColor color = { 0, 0, 0, 0, }; - GdkColor *pcolor; - int have_pixel; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_POLYGON (object)); - - item = FOO_CANVAS_ITEM (object); - poly = FOO_CANVAS_POLYGON (object); - have_pixel = FALSE; - - switch (param_id) { - case PROP_POINTS: - points = g_value_get_boxed (value); - - if (poly->coords) { - g_free (poly->coords); - poly->coords = NULL; - } - - if (!points) - poly->num_points = 0; - else - set_points (poly, points); - - foo_canvas_item_request_update (item); - break; - - case PROP_FILL_COLOR: - case PROP_FILL_COLOR_GDK: - case PROP_FILL_COLOR_RGBA: - switch (param_id) { - case PROP_FILL_COLOR: - if (g_value_get_string (value) && - gdk_color_parse (g_value_get_string (value), &color)) - poly->fill_set = TRUE; - else - poly->fill_set = FALSE; - - poly->fill_color = ((color.red & 0xff00) << 16 | - (color.green & 0xff00) << 8 | - (color.blue & 0xff00) | - 0xff); - break; - - case PROP_FILL_COLOR_GDK: - pcolor = g_value_get_boxed (value); - poly->fill_set = pcolor != NULL; - - if (pcolor) { - GdkColormap *colormap; - - color = *pcolor; - colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); - gdk_rgb_find_color (colormap, &color); - have_pixel = TRUE; - } - - poly->fill_color = ((color.red & 0xff00) << 16 | - (color.green & 0xff00) << 8 | - (color.blue & 0xff00) | - 0xff); - break; - - case PROP_FILL_COLOR_RGBA: - poly->fill_set = TRUE; - poly->fill_color = g_value_get_uint (value); - break; - } -#ifdef VERBOSE - g_print ("poly fill color = %08x\n", poly->fill_color); -#endif - if (have_pixel) - poly->fill_pixel = color.pixel; - else - poly->fill_pixel = foo_canvas_get_color_pixel (item->canvas, - poly->fill_color); - - set_gc_foreground (poly->fill_gc, poly->fill_pixel); - foo_canvas_item_request_redraw (item); - break; - - case PROP_OUTLINE_COLOR: - case PROP_OUTLINE_COLOR_GDK: - case PROP_OUTLINE_COLOR_RGBA: - switch (param_id) { - case PROP_OUTLINE_COLOR: - if (g_value_get_string (value) && - gdk_color_parse (g_value_get_string (value), &color)) - poly->outline_set = TRUE; - else - poly->outline_set = FALSE; - - poly->outline_color = ((color.red & 0xff00) << 16 | - (color.green & 0xff00) << 8 | - (color.blue & 0xff00) | - 0xff); - break; - - case PROP_OUTLINE_COLOR_GDK: - pcolor = g_value_get_boxed (value); - poly->outline_set = pcolor != NULL; - - if (pcolor) { - GdkColormap *colormap; - - color = *pcolor; - colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); - gdk_rgb_find_color (colormap, &color); - have_pixel = TRUE; - } - - poly->outline_color = ((color.red & 0xff00) << 16 | - (color.green & 0xff00) << 8 | - (color.blue & 0xff00) | - 0xff); - break; - - case PROP_OUTLINE_COLOR_RGBA: - poly->outline_set = TRUE; - poly->outline_color = g_value_get_uint (value); - break; - } -#ifdef VERBOSE - g_print ("poly outline color = %08x\n", poly->outline_color); -#endif - if (have_pixel) - poly->outline_pixel = color.pixel; - else - poly->outline_pixel = foo_canvas_get_color_pixel (item->canvas, - poly->outline_color); - - set_gc_foreground (poly->outline_gc, poly->outline_pixel); - foo_canvas_item_request_redraw (item); - break; - - case PROP_FILL_STIPPLE: - set_stipple (poly->fill_gc, &poly->fill_stipple, (GdkBitmap *) g_value_get_object (value), FALSE); - foo_canvas_item_request_update (item); - break; - - case PROP_OUTLINE_STIPPLE: - set_stipple (poly->outline_gc, &poly->outline_stipple, (GdkBitmap *) g_value_get_object (value), FALSE); - foo_canvas_item_request_update (item); - break; - - case PROP_WIDTH_PIXELS: - poly->width = g_value_get_uint (value); - poly->width_pixels = TRUE; - set_outline_gc_width (poly); -#ifdef OLD_XFORM - recalc_bounds (poly); -#else - foo_canvas_item_request_update (item); -#endif - break; - - case PROP_WIDTH_UNITS: - poly->width = fabs (g_value_get_double (value)); - poly->width_pixels = FALSE; - set_outline_gc_width (poly); -#ifdef OLD_XFORM - recalc_bounds (poly); -#else - foo_canvas_item_request_update (item); -#endif - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -/* Allocates a GdkColor structure filled with the specified pixel, and puts it into the specified - * value for returning it in the get_property method. - */ -static void -get_color_value (FooCanvasPolygon *poly, gulong pixel, GValue *value) -{ - GdkColor color; - GdkColormap *colormap; - - colormap = gtk_widget_get_colormap (GTK_WIDGET (FOO_CANVAS_ITEM(poly)->canvas)); - gdk_colormap_query_color(colormap, pixel, &color); - g_value_set_boxed (value, &color); -} - -static void -foo_canvas_polygon_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec) -{ - FooCanvasPolygon *poly; - FooCanvasPoints *points; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_POLYGON (object)); - - poly = FOO_CANVAS_POLYGON (object); - - switch (param_id) { - case PROP_POINTS: - if (poly->num_points != 0) { - points = foo_canvas_points_new (poly->num_points); - memcpy (points->coords, poly->coords, 2 * poly->num_points * sizeof (double)); - g_value_set_boxed (value, points); - } else - g_value_set_boxed (value, NULL); - break; - - case PROP_FILL_COLOR_GDK: - get_color_value (poly, poly->fill_pixel, value); - break; - - case PROP_OUTLINE_COLOR_GDK: - get_color_value (poly, poly->outline_pixel, value); - break; - - case PROP_FILL_COLOR_RGBA: - g_value_set_uint (value, poly->fill_color); - break; - - case PROP_OUTLINE_COLOR_RGBA: - g_value_set_uint (value, poly->outline_color); - break; - - case PROP_FILL_STIPPLE: - g_value_set_object (value, (GObject *) poly->fill_stipple); - break; - - case PROP_OUTLINE_STIPPLE: - g_value_set_object (value, (GObject *) poly->outline_stipple); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -static void -foo_canvas_polygon_update (FooCanvasItem *item, - double i2w_dx, double i2w_dy, - int flags) -{ - FooCanvasPolygon *poly; - double x1, y1, x2, y2; - - poly = FOO_CANVAS_POLYGON (item); - - if (parent_class->update) - (* parent_class->update) (item, i2w_dx, i2w_dy, flags); - - set_outline_gc_width (poly); - set_gc_foreground (poly->fill_gc, poly->fill_pixel); - set_gc_foreground (poly->outline_gc, poly->outline_pixel); - set_stipple (poly->fill_gc, &poly->fill_stipple, poly->fill_stipple, TRUE); - set_stipple (poly->outline_gc, &poly->outline_stipple, poly->outline_stipple, TRUE); - - if(get_bounds_canvas (poly, &x1, &y1, &x2, &y2, i2w_dx, i2w_dy)) - foo_canvas_update_bbox (item, x1, y1, x2, y2); -} - -static void -foo_canvas_polygon_realize (FooCanvasItem *item) -{ - FooCanvasPolygon *poly; - - poly = FOO_CANVAS_POLYGON (item); - - if (parent_class->realize) - (* parent_class->realize) (item); - - poly->fill_gc = gdk_gc_new (item->canvas->layout.bin_window); - poly->outline_gc = gdk_gc_new (item->canvas->layout.bin_window); -#warning "FIXME: Need to recalc pixel values, set colours, etc." - -#ifdef OLD_XFORM - (* FOO_CANVAS_ITEM_CLASS (item->object.klass)->update) (item, NULL, NULL, 0); -#endif -} - -static void -foo_canvas_polygon_unrealize (FooCanvasItem *item) -{ - FooCanvasPolygon *poly; - - poly = FOO_CANVAS_POLYGON (item); - - g_object_unref (poly->fill_gc); - poly->fill_gc = NULL; - g_object_unref (poly->outline_gc); - poly->outline_gc = NULL; - - if (parent_class->unrealize) - (* parent_class->unrealize) (item); -} - -/* Converts an array of world coordinates into an array of canvas pixel coordinates. Takes in the - * item->world deltas and the drawable deltas. - */ -static void -item_to_canvas (FooCanvas *canvas, double *item_coords, GdkPoint *canvas_coords, int num_points, - double i2w_dx, double i2w_dy) -{ - int i; - - for (i = 0; i < num_points; i++) { - foo_canvas_w2c (canvas, - item_coords[i*2] + i2w_dx, - item_coords[i*2+1] + i2w_dy, - &canvas_coords->x, &canvas_coords->y); - canvas_coords++; - } -} - -static void -foo_canvas_polygon_draw (FooCanvasItem *item, GdkDrawable *drawable, - GdkEventExpose *expose) -{ - FooCanvasPolygon *poly; - GdkPoint static_points[NUM_STATIC_POINTS]; - GdkPoint *points; - double i2w_dx, i2w_dy; - - poly = FOO_CANVAS_POLYGON (item); - - if (poly->num_points == 0) - return; - - /* Build array of canvas pixel coordinates */ - - if (poly->num_points <= NUM_STATIC_POINTS) - points = static_points; - else - points = g_new (GdkPoint, poly->num_points); - - i2w_dx = 0.0; - i2w_dy = 0.0; - foo_canvas_item_i2w (item, &i2w_dx, &i2w_dy); - - item_to_canvas (item->canvas, - poly->coords, points, poly->num_points, - i2w_dx, i2w_dy); - - if (poly->fill_set) { - if (poly->fill_stipple) - foo_canvas_set_stipple_origin (item->canvas, poly->fill_gc); - - gdk_draw_polygon (drawable, poly->fill_gc, TRUE, points, poly->num_points); - } - - if (poly->outline_set) { - if (poly->outline_stipple) - foo_canvas_set_stipple_origin (item->canvas, poly->outline_gc); - - gdk_draw_polygon (drawable, poly->outline_gc, FALSE, points, poly->num_points); - } - - /* Done */ - - if (points != static_points) - g_free (points); -} - -static double -foo_canvas_polygon_point (FooCanvasItem *item, double x, double y, - int cx, int cy, FooCanvasItem **actual_item) -{ - FooCanvasPolygon *poly; - double dist; - double width; - - poly = FOO_CANVAS_POLYGON (item); - - *actual_item = item; - - dist = foo_canvas_polygon_to_point (poly->coords, poly->num_points, x, y); - - if (poly->outline_set) { - if (poly->width_pixels) - width = poly->width / item->canvas->pixels_per_unit_x; - else - width = poly->width; - - dist -= width / 2.0; - - if (dist < 0.0) - dist = 0.0; - } - - return dist; -} - -static void -foo_canvas_polygon_translate (FooCanvasItem *item, double dx, double dy) -{ - FooCanvasPolygon *poly; - int i; - double *coords; - - poly = FOO_CANVAS_POLYGON (item); - - for (i = 0, coords = poly->coords; i < poly->num_points; i++, coords += 2) { - coords[0] += dx; - coords[1] += dy; - } - -} - -static void -foo_canvas_polygon_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2) -{ - FooCanvasPolygon *poly; - - g_return_if_fail (item != NULL); - g_return_if_fail (FOO_IS_CANVAS_POLYGON (item)); - - poly = FOO_CANVAS_POLYGON (item); - - if (poly->num_points == 0) { - *x1 = *y1 = *x2 = *y2 = 0.0; - return; - } - - get_bounds (poly, x1, y1, x2, y2); -} diff --git a/foocanvas/foo-canvas-rect-ellipse.c b/foocanvas/foo-canvas-rect-ellipse.c deleted file mode 100755 index 7c38948f6..000000000 --- a/foocanvas/foo-canvas-rect-ellipse.c +++ /dev/null @@ -1,1490 +0,0 @@ -/* Last edited: Feb 25 11:09 2005 (rds) */ -/* - * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation - * All rights reserved. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with the Gnome Library; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -/* - @NOTATION@ - */ -/* Rectangle and ellipse item types for FooCanvas widget - * - * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget. Tk is - * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties. - * - * - * Author: Federico Mena <federico@nuclecu.unam.mx> - */ - -#include <config.h> -#include <math.h> -#include "foo-canvas-rect-ellipse.h" -#include "foo-canvas-util.h" -#include <string.h> - -#ifdef HAVE_RENDER -#include <gdk/gdkx.h> -#include <X11/extensions/Xrender.h> -#endif - -/* Base class for rectangle and ellipse item types */ - -#define noVERBOSE - -enum { - PROP_0, - PROP_X1, - PROP_Y1, - PROP_X2, - PROP_Y2, - PROP_FILL_COLOR, - PROP_FILL_COLOR_GDK, - PROP_FILL_COLOR_RGBA, - PROP_OUTLINE_COLOR, - PROP_OUTLINE_COLOR_GDK, - PROP_OUTLINE_COLOR_RGBA, - PROP_FILL_STIPPLE, - PROP_OUTLINE_STIPPLE, - PROP_WIDTH_PIXELS, - PROP_WIDTH_UNITS -}; - - -static void foo_canvas_re_class_init (FooCanvasREClass *class); -static void foo_canvas_re_init (FooCanvasRE *re); -static void foo_canvas_re_destroy (GtkObject *object); -static void foo_canvas_re_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec); -static void foo_canvas_re_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec); - -static void foo_canvas_re_update_shared (FooCanvasItem *item, - double i2w_dx, double i2w_dy, int flags); -static void foo_canvas_re_realize (FooCanvasItem *item); -static void foo_canvas_re_unrealize (FooCanvasItem *item); -static void foo_canvas_re_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2); -static void foo_canvas_re_translate (FooCanvasItem *item, double dx, double dy); -static void foo_canvas_rect_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags); -static void foo_canvas_ellipse_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags); - -typedef struct { - /*< public >*/ - int x0, y0, x1, y1; -} Rect; - -static Rect make_rect (int x0, int y0, int x1, int y1); -static void diff_rects (Rect r1, Rect r2, int *count, Rect result[4]); - -static FooCanvasItemClass *re_parent_class; -static FooCanvasREClass *rect_parent_class; - - -GType -foo_canvas_re_get_type (void) -{ - static GType re_type = 0; - - if (!re_type) { - GTypeInfo re_info = { - sizeof (FooCanvasREClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) foo_canvas_re_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (FooCanvasRE), - 0, /* n_preallocs */ - (GInstanceInitFunc) foo_canvas_re_init - }; - - re_type = g_type_register_static (foo_canvas_item_get_type (), - "FooCanvasRE", - &re_info, - 0); - } - - return re_type; -} - -static void -foo_canvas_re_class_init (FooCanvasREClass *class) -{ - GObjectClass *gobject_class; - GtkObjectClass *object_class; - FooCanvasItemClass *item_class; - - gobject_class = (GObjectClass *) class; - object_class = (GtkObjectClass *) class; - item_class = (FooCanvasItemClass *) class; - - re_parent_class = g_type_class_peek_parent (class); - - gobject_class->set_property = foo_canvas_re_set_property; - gobject_class->get_property = foo_canvas_re_get_property; - - g_object_class_install_property - (gobject_class, - PROP_X1, - g_param_spec_double ("x1", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_Y1, - g_param_spec_double ("y1", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_X2, - g_param_spec_double ("x2", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_Y2, - g_param_spec_double ("y2", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FILL_COLOR, - g_param_spec_string ("fill_color", NULL, NULL, - NULL, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FILL_COLOR_GDK, - g_param_spec_boxed ("fill_color_gdk", NULL, NULL, - GDK_TYPE_COLOR, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FILL_COLOR_RGBA, - g_param_spec_uint ("fill_color_rgba", NULL, NULL, - 0, G_MAXUINT, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FILL_STIPPLE, - g_param_spec_object ("fill_stipple", NULL, NULL, - GDK_TYPE_DRAWABLE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_OUTLINE_COLOR, - g_param_spec_string ("outline_color", NULL, NULL, - NULL, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_OUTLINE_COLOR_GDK, - g_param_spec_boxed ("outline_color_gdk", NULL, NULL, - GDK_TYPE_COLOR, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_OUTLINE_COLOR_RGBA, - g_param_spec_uint ("outline_color_rgba", NULL, NULL, - 0, G_MAXUINT, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_OUTLINE_STIPPLE, - g_param_spec_object ("outline_stipple", NULL, NULL, - GDK_TYPE_DRAWABLE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_WIDTH_PIXELS, - g_param_spec_uint ("width_pixels", NULL, NULL, - 0, G_MAXUINT, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_WIDTH_UNITS, - g_param_spec_double ("width_units", NULL, NULL, - 0.0, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - - object_class->destroy = foo_canvas_re_destroy; - - item_class->realize = foo_canvas_re_realize; - item_class->unrealize = foo_canvas_re_unrealize; - item_class->translate = foo_canvas_re_translate; - item_class->bounds = foo_canvas_re_bounds; -} - -static void -foo_canvas_re_init (FooCanvasRE *re) -{ - re->x1 = 0.0; - re->y1 = 0.0; - re->x2 = 0.0; - re->y2 = 0.0; - re->width = 0.0; -} - -static void -foo_canvas_re_destroy (GtkObject *object) -{ - FooCanvasRE *re; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_RE (object)); - - re = FOO_CANVAS_RE (object); - - /* remember, destroy can be run multiple times! */ - - if (re->fill_stipple) - g_object_unref (re->fill_stipple); - re->fill_stipple = NULL; - - if (re->outline_stipple) - g_object_unref (re->outline_stipple); - re->outline_stipple = NULL; - - if (GTK_OBJECT_CLASS (re_parent_class)->destroy) - (* GTK_OBJECT_CLASS (re_parent_class)->destroy) (object); -} - -static void get_bounds (FooCanvasRE *re, double *px1, double *py1, double *px2, double *py2) -{ - FooCanvasItem *item; - double x1, y1, x2, y2; - int cx1, cy1, cx2, cy2; - double hwidth; - -#ifdef VERBOSE - g_print ("re get_bounds\n"); -#endif - item = FOO_CANVAS_ITEM (re); - - if (re->width_pixels) - hwidth = (re->width / item->canvas->pixels_per_unit_x) / 2.0; - else - hwidth = re->width / 2.0; - - x1 = re->x1; - y1 = re->y1; - x2 = re->x2; - y2 = re->y2; - - foo_canvas_item_i2w (item, &x1, &y1); - foo_canvas_item_i2w (item, &x2, &y2); - foo_canvas_w2c (item->canvas, x1 - hwidth, y1 - hwidth, &cx1, &cy1); - foo_canvas_w2c (item->canvas, x2 + hwidth, y2 + hwidth, &cx2, &cy2); - *px1 = cx1; - *py1 = cy1; - *px2 = cx2; - *py2 = cy2; - - /* Some safety fudging */ - - *px1 -= 2; - *py1 -= 2; - *px2 += 2; - *py2 += 2; -} - -/* Convenience function to set a GC's foreground color to the specified pixel value */ -static void -set_gc_foreground (GdkGC *gc, gulong pixel) -{ - GdkColor c; - - if (!gc) - return; - - c.pixel = pixel; - gdk_gc_set_foreground (gc, &c); -} - -/* Sets the stipple pattern for the specified gc */ -static void -set_stipple (GdkGC *gc, GdkBitmap **internal_stipple, GdkBitmap *stipple, int reconfigure) -{ - if (*internal_stipple && !reconfigure) - g_object_unref (*internal_stipple); - - *internal_stipple = stipple; - if (stipple && !reconfigure) - g_object_ref (stipple); - - if (gc) { - if (stipple) { - gdk_gc_set_stipple (gc, stipple); - gdk_gc_set_fill (gc, GDK_STIPPLED); - } else - gdk_gc_set_fill (gc, GDK_SOLID); - } -} - -/* Recalculate the outline width of the rectangle/ellipse and set it in its GC */ -static void -set_outline_gc_width (FooCanvasRE *re) -{ - int width; - - if (!re->outline_gc) - return; - - if (re->width_pixels) - width = (int) re->width; - else - width = (int) (re->width * re->item.canvas->pixels_per_unit_x + 0.5); - - gdk_gc_set_line_attributes (re->outline_gc, width, - GDK_LINE_SOLID, GDK_CAP_PROJECTING, GDK_JOIN_MITER); -} - -static void -foo_canvas_re_set_fill (FooCanvasRE *re, gboolean fill_set) -{ - if (re->fill_set != fill_set) { - re->fill_set = fill_set; - foo_canvas_item_request_update (FOO_CANVAS_ITEM (re)); - } -} - -static void -foo_canvas_re_set_outline (FooCanvasRE *re, gboolean outline_set) -{ - if (re->outline_set != outline_set) { - re->outline_set = outline_set; - foo_canvas_item_request_update (FOO_CANVAS_ITEM (re)); - } -} - -static void -foo_canvas_re_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) -{ - FooCanvasItem *item; - FooCanvasRE *re; - GdkColor color = { 0, 0, 0, 0, }; - GdkColor *pcolor; - int have_pixel; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_RE (object)); - - item = FOO_CANVAS_ITEM (object); - re = FOO_CANVAS_RE (object); - have_pixel = FALSE; - - switch (param_id) { - case PROP_X1: - re->x1 = g_value_get_double (value); - - foo_canvas_item_request_update (item); - break; - - case PROP_Y1: - re->y1 = g_value_get_double (value); - - foo_canvas_item_request_update (item); - break; - - case PROP_X2: - re->x2 = g_value_get_double (value); - - foo_canvas_item_request_update (item); - break; - - case PROP_Y2: - re->y2 = g_value_get_double (value); - - foo_canvas_item_request_update (item); - break; - - case PROP_FILL_COLOR: - case PROP_FILL_COLOR_GDK: - case PROP_FILL_COLOR_RGBA: - switch (param_id) { - case PROP_FILL_COLOR: - if (g_value_get_string (value) && - gdk_color_parse (g_value_get_string (value), &color)) - foo_canvas_re_set_fill (re, TRUE); - else - foo_canvas_re_set_fill (re, FALSE); - - re->fill_color = ((color.red & 0xff00) << 16 | - (color.green & 0xff00) << 8 | - (color.blue & 0xff00) | - 0xff); - break; - - case PROP_FILL_COLOR_GDK: - pcolor = g_value_get_boxed (value); - foo_canvas_re_set_fill (re, pcolor != NULL); - - if (pcolor) { - GdkColormap *colormap; - - color = *pcolor; - colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); - gdk_rgb_find_color (colormap, &color); - have_pixel = TRUE; - } - - re->fill_color = ((color.red & 0xff00) << 16 | - (color.green & 0xff00) << 8 | - (color.blue & 0xff00) | - 0xff); - break; - - case PROP_FILL_COLOR_RGBA: - foo_canvas_re_set_fill (re, TRUE); - re->fill_color = g_value_get_uint (value); - break; - } -#ifdef VERBOSE - g_print ("re fill color = %08x\n", re->fill_color); -#endif - if (have_pixel) - re->fill_pixel = color.pixel; - else - re->fill_pixel = foo_canvas_get_color_pixel (item->canvas, re->fill_color); - - set_gc_foreground (re->fill_gc, re->fill_pixel); - - foo_canvas_item_request_redraw (item); - break; - - case PROP_OUTLINE_COLOR: - case PROP_OUTLINE_COLOR_GDK: - case PROP_OUTLINE_COLOR_RGBA: - switch (param_id) { - case PROP_OUTLINE_COLOR: - if (g_value_get_string (value) && - gdk_color_parse (g_value_get_string (value), &color)) - foo_canvas_re_set_outline (re, TRUE); - else - foo_canvas_re_set_outline (re, FALSE); - - re->outline_color = ((color.red & 0xff00) << 16 | - (color.green & 0xff00) << 8 | - (color.blue & 0xff00) | - 0xff); - break; - - case PROP_OUTLINE_COLOR_GDK: - pcolor = g_value_get_boxed (value); - foo_canvas_re_set_outline (re, pcolor != NULL); - - if (pcolor) { - GdkColormap *colormap; - - color = *pcolor; - colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); - gdk_rgb_find_color (colormap, &color); - - have_pixel = TRUE; - } - - re->outline_color = ((color.red & 0xff00) << 16 | - (color.green & 0xff00) << 8 | - (color.blue & 0xff00) | - 0xff); - break; - - case PROP_OUTLINE_COLOR_RGBA: - foo_canvas_re_set_outline (re, TRUE); - re->outline_color = g_value_get_uint (value); - break; - } -#ifdef VERBOSE - g_print ("re outline color %x %x %x\n", color.red, color.green, color.blue); -#endif - if (have_pixel) - re->outline_pixel = color.pixel; - else - re->outline_pixel = foo_canvas_get_color_pixel (item->canvas, - re->outline_color); - - set_gc_foreground (re->outline_gc, re->outline_pixel); - - foo_canvas_item_request_redraw (item); - break; - - case PROP_FILL_STIPPLE: - set_stipple (re->fill_gc, &re->fill_stipple, (GdkBitmap *) g_value_get_object (value), FALSE); - - break; - - case PROP_OUTLINE_STIPPLE: - set_stipple (re->outline_gc, &re->outline_stipple, (GdkBitmap *) g_value_get_object (value), FALSE); - break; - - case PROP_WIDTH_PIXELS: - re->width = g_value_get_uint (value); - re->width_pixels = TRUE; - set_outline_gc_width (re); - - foo_canvas_item_request_update (item); - break; - - case PROP_WIDTH_UNITS: - re->width = fabs (g_value_get_double (value)); - re->width_pixels = FALSE; - set_outline_gc_width (re); - - foo_canvas_item_request_update (item); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -/* Allocates a GdkColor structure filled with the specified pixel, and puts it into the specified - * value for returning it in the get_property method. - */ -static void -get_color_value (FooCanvasRE *re, gulong pixel, GValue *value) -{ - GdkColor color; - FooCanvasItem *item = (FooCanvasItem *) re; - GdkColormap *colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); - - gdk_colormap_query_color (colormap, pixel, &color); - g_value_set_boxed (value, &color); -} - -static void -foo_canvas_re_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec) -{ - FooCanvasRE *re; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_RE (object)); - - re = FOO_CANVAS_RE (object); - - switch (param_id) { - case PROP_X1: - g_value_set_double (value, re->x1); - break; - - case PROP_Y1: - g_value_set_double (value, re->y1); - break; - - case PROP_X2: - g_value_set_double (value, re->x2); - break; - - case PROP_Y2: - g_value_set_double (value, re->y2); - break; - - case PROP_FILL_COLOR_GDK: - get_color_value (re, re->fill_pixel, value); - break; - - case PROP_OUTLINE_COLOR_GDK: - get_color_value (re, re->outline_pixel, value); - break; - - case PROP_FILL_COLOR_RGBA: - g_value_set_uint (value, re->fill_color); - break; - - case PROP_OUTLINE_COLOR_RGBA: - g_value_set_uint (value, re->outline_color); - break; - - case PROP_FILL_STIPPLE: - g_value_set_object (value, (GObject *) re->fill_stipple); - break; - - case PROP_OUTLINE_STIPPLE: - g_value_set_object (value, (GObject *) re->outline_stipple); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -static void -set_colors_and_stipples (FooCanvasRE *re) -{ - set_gc_foreground (re->fill_gc, re->fill_pixel); - set_gc_foreground (re->outline_gc, re->outline_pixel); - set_stipple (re->fill_gc, &re->fill_stipple, re->fill_stipple, TRUE); - set_stipple (re->outline_gc, &re->outline_stipple, re->outline_stipple, TRUE); - set_outline_gc_width (re); -} - -static void -foo_canvas_re_update_shared (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags) -{ - FooCanvasRE *re; - -#ifdef VERBOSE - g_print ("foo_canvas_re_update_shared\n"); -#endif - re = FOO_CANVAS_RE (item); - - if (re_parent_class->update) - (* re_parent_class->update) (item, i2w_dx, i2w_dy, flags); - - set_colors_and_stipples (re); - -#ifdef OLD_XFORM - recalc_bounds (re); -#endif -} - -static void -foo_canvas_re_realize (FooCanvasItem *item) -{ - FooCanvasRE *re; - -#ifdef VERBOSE - g_print ("foo_canvas_re_realize\n"); -#endif - re = FOO_CANVAS_RE (item); - - if (re_parent_class->realize) - (* re_parent_class->realize) (item); - - re->fill_gc = gdk_gc_new (item->canvas->layout.bin_window); - re->fill_pixel = foo_canvas_get_color_pixel (item->canvas, re->fill_color); - re->outline_gc = gdk_gc_new (item->canvas->layout.bin_window); - re->outline_pixel = foo_canvas_get_color_pixel (item->canvas, re->outline_color); - set_colors_and_stipples (re); - -#ifdef OLD_XFORM - (* FOO_CANVAS_ITEM_CLASS (item->object.klass)->update) (item, NULL, NULL, 0); -#endif -} - -static void -foo_canvas_re_unrealize (FooCanvasItem *item) -{ - FooCanvasRE *re; - - re = FOO_CANVAS_RE (item); - - g_object_unref (re->fill_gc); - re->fill_gc = NULL; - g_object_unref (re->outline_gc); - re->outline_gc = NULL; - - if (re_parent_class->unrealize) - (* re_parent_class->unrealize) (item); -} - -static void -foo_canvas_re_translate (FooCanvasItem *item, double dx, double dy) -{ - FooCanvasRE *re; - -#ifdef VERBOSE - g_print ("foo_canvas_re_translate\n"); -#endif - re = FOO_CANVAS_RE (item); - - re->x1 += dx; - re->y1 += dy; - re->x2 += dx; - re->y2 += dy; -} - - -static void -foo_canvas_re_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2) -{ - FooCanvasRE *re; - double hwidth; - -#ifdef VERBOSE - g_print ("foo_canvas_re_bounds\n"); -#endif - re = FOO_CANVAS_RE (item); - - if (re->width_pixels) - hwidth = (re->width / item->canvas->pixels_per_unit_x) / 2.0; - else - hwidth = re->width / 2.0; - - *x1 = re->x1 - hwidth; - *y1 = re->y1 - hwidth; - *x2 = re->x2 + hwidth; - *y2 = re->y2 + hwidth; -} - -/* Rectangle item */ - - -static void foo_canvas_rect_class_init (FooCanvasRectClass *class); -static void foo_canvas_rect_init (FooCanvasRect *rect); -static void foo_canvas_rect_finalize (GObject *object); -static void foo_canvas_rect_realize (FooCanvasItem *item); - -static void foo_canvas_rect_draw (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose); -static double foo_canvas_rect_point (FooCanvasItem *item, double x, double y, int cx, int cy, - FooCanvasItem **actual_item); - -struct _FooCanvasRectPrivate { - Rect last_update_rect; - Rect last_outline_update_rect; - int last_outline_update_width; - -#ifdef HAVE_RENDER - gboolean use_render; - XRenderPictFormat *format; -#endif -}; - -GType -foo_canvas_rect_get_type (void) -{ - static GType rect_type = 0; - - if (!rect_type) { - GTypeInfo rect_info = { - sizeof (FooCanvasRectClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) foo_canvas_rect_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (FooCanvasRect), - 0, /* n_preallocs */ - (GInstanceInitFunc) foo_canvas_rect_init - }; - - rect_type = g_type_register_static (foo_canvas_re_get_type (), - "FooCanvasRect", - &rect_info, - 0); - } - - return rect_type; -} - -static void -foo_canvas_rect_class_init (FooCanvasRectClass *class) -{ - FooCanvasItemClass *item_class; - - rect_parent_class = g_type_class_peek_parent (class); - - item_class = (FooCanvasItemClass *) class; - - item_class->draw = foo_canvas_rect_draw; - item_class->point = foo_canvas_rect_point; - item_class->update = foo_canvas_rect_update; - item_class->realize = foo_canvas_rect_realize; - - G_OBJECT_CLASS (class)->finalize = foo_canvas_rect_finalize; - -} - -static void -foo_canvas_rect_init (FooCanvasRect *rect) -{ - rect->priv = g_new0 (FooCanvasRectPrivate, 1); -} - -static void -foo_canvas_rect_finalize (GObject *object) -{ - FooCanvasRect *rect = FOO_CANVAS_RECT (object); - - if (rect->priv) { - g_free (rect->priv); - } - - G_OBJECT_CLASS (rect_parent_class)->finalize (object); -} - -static void -foo_canvas_rect_realize (FooCanvasItem *item) -{ -#ifdef HAVE_RENDER - FooCanvasRectPrivate *priv; - int event_base, error_base; - - priv = FOO_CANVAS_RECT (item)->priv; - - priv->use_render = XRenderQueryExtension (gdk_display, &event_base, &error_base); - - if (priv->use_render) { - Display *dpy; - GdkVisual *gdk_visual; - Visual *visual; - - dpy = gdk_x11_drawable_get_xdisplay (GTK_WIDGET (item->canvas)->window); - gdk_visual = gtk_widget_get_visual (GTK_WIDGET (item->canvas)); - visual = gdk_x11_visual_get_xvisual (gdk_visual); - - priv->format = XRenderFindVisualFormat (dpy, visual); - } -#endif - - if (FOO_CANVAS_ITEM_CLASS (rect_parent_class)->realize) { - (* FOO_CANVAS_ITEM_CLASS (rect_parent_class)->realize) (item); - } -} - - -static void -render_rect_alpha (FooCanvasRect *rect, - GdkDrawable *drawable, - int x, int y, - int width, int height, - guint32 rgba) -{ - GdkPixbuf *pixbuf; - guchar *data; - int rowstride, i; - guchar r, g, b, a; - FooCanvasRectPrivate *priv; - - if (width <= 0 || height <= 0 ) { - return; - } - - priv = rect->priv; - - r = (rgba >> 24) & 0xff; - g = (rgba >> 16) & 0xff; - b = (rgba >> 8) & 0xff; - a = (rgba >> 0) & 0xff; - -#ifdef HAVE_RENDER - /* Every visual is not guaranteed to have a matching - * XRenderPictFormat. So make sure that format is not null before - * trying to render using Xrender calls. - */ - if (priv->use_render && (priv->format != NULL)) { - GdkDrawable *real_drawable; - int x_offset, y_offset; - - Display *dpy; - Picture pict; - XRenderPictureAttributes attributes; - XRenderColor color; - - gdk_window_get_internal_paint_info (drawable, &real_drawable, - &x_offset, &y_offset); - - dpy = gdk_x11_drawable_get_xdisplay (real_drawable); - - pict = XRenderCreatePicture (dpy, - gdk_x11_drawable_get_xid (real_drawable), - priv->format, - 0, - &attributes); - - - /* Convert to premultiplied alpha: */ - r = r * a / 255; - g = g * a / 255; - b = b * a / 255; - - color.red = (r << 8) + r; - color.green = (g << 8) + g; - color.blue = (b << 8) + b; - color.alpha = (a << 8) + a; - - XRenderFillRectangle (dpy, - PictOpOver, - pict, - &color, - x - x_offset, y - y_offset, - width, height); - - XRenderFreePicture (dpy, pict); - - return; - } -#endif - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height); - data = gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - - r = (rgba >> 24) & 0xff; - g = (rgba >> 16) & 0xff; - b = (rgba >> 8) & 0xff; - a = (rgba >> 0) & 0xff; - - for (i = 0; i < width*4; ) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a; - } - - for (i = 1; i < height; i++) { - memcpy (data + i*rowstride, data, width*4); - } - - gdk_draw_pixbuf (drawable, NULL, pixbuf, - 0, 0, x, y, width, height, - GDK_RGB_DITHER_NONE, 0, 0); - g_object_unref (pixbuf); -} - - -static void -foo_canvas_rect_draw (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose) -{ - FooCanvasRE *re; - double x1, y1, x2, y2; - int cx1, cy1, cx2, cy2; - double i2w_dx, i2w_dy; - - re = FOO_CANVAS_RE (item); - - /* Get canvas pixel coordinates */ - i2w_dx = 0.0; - i2w_dy = 0.0; - foo_canvas_item_i2w (item, &i2w_dx, &i2w_dy); - - x1 = re->x1 + i2w_dx; - y1 = re->y1 + i2w_dy; - x2 = re->x2 + i2w_dx; - y2 = re->y2 + i2w_dy; - - foo_canvas_w2c (item->canvas, x1, y1, &cx1, &cy1); - foo_canvas_w2c (item->canvas, x2, y2, &cx2, &cy2); - - if (re->fill_set) { - if ((re->fill_color & 0xff) != 255) { - GdkRectangle *rectangles; - gint i, n_rectangles; - GdkRectangle draw_rect; - GdkRectangle part; - - draw_rect.x = cx1; - draw_rect.y = cy1; - draw_rect.width = cx2 - cx1 + 1; - draw_rect.height = cy2 - cy1 + 1; - - /* For alpha mode, only render the parts of the region - that are actually exposed */ - gdk_region_get_rectangles (expose->region, - &rectangles, - &n_rectangles); - - for (i = 0; i < n_rectangles; i++) { - if (gdk_rectangle_intersect (&rectangles[i], - &draw_rect, - &part)) { - render_rect_alpha (FOO_CANVAS_RECT (item), - drawable, - part.x, part.y, - part.width, part.height, - re->fill_color); - } - } - - g_free (rectangles); - } else { - if (re->fill_stipple) - foo_canvas_set_stipple_origin (item->canvas, re->fill_gc); - - gdk_draw_rectangle (drawable, - re->fill_gc, - TRUE, - cx1, cy1, - cx2 - cx1 + 1, - cy2 - cy1 + 1); - } - } - - if (re->outline_set) { - if (re->outline_stipple) - foo_canvas_set_stipple_origin (item->canvas, re->outline_gc); - - gdk_draw_rectangle (drawable, - re->outline_gc, - FALSE, - cx1, - cy1, - cx2 - cx1, - cy2 - cy1); - } -} - -static double -foo_canvas_rect_point (FooCanvasItem *item, double x, double y, int cx, int cy, FooCanvasItem **actual_item) -{ - FooCanvasRE *re; - double x1, y1, x2, y2; - double hwidth; - double dx, dy; - double tmp; - -#ifdef VERBOSE - g_print ("foo_canvas_rect_point\n"); -#endif - re = FOO_CANVAS_RE (item); - - *actual_item = item; - - /* Find the bounds for the rectangle plus its outline width */ - - x1 = re->x1; - y1 = re->y1; - x2 = re->x2; - y2 = re->y2; - - if (re->outline_set) { - if (re->width_pixels) - hwidth = (re->width / item->canvas->pixels_per_unit_x) / 2.0; - else - hwidth = re->width / 2.0; - - x1 -= hwidth; - y1 -= hwidth; - x2 += hwidth; - y2 += hwidth; - } else - hwidth = 0.0; - - /* Is point inside rectangle (which can be hollow if it has no fill set)? */ - - if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) { - if (re->fill_set || !re->outline_set) - return 0.0; - - dx = x - x1; - tmp = x2 - x; - if (tmp < dx) - dx = tmp; - - dy = y - y1; - tmp = y2 - y; - if (tmp < dy) - dy = tmp; - - if (dy < dx) - dx = dy; - - dx -= 2.0 * hwidth; - - if (dx < 0.0) - return 0.0; - else - return dx; - } - - /* Point is outside rectangle */ - - if (x < x1) - dx = x1 - x; - else if (x > x2) - dx = x - x2; - else - dx = 0.0; - - if (y < y1) - dy = y1 - y; - else if (y > y2) - dy = y - y2; - else - dy = 0.0; - - return sqrt (dx * dx + dy * dy); -} - -static void -request_redraw_borders (FooCanvas *canvas, - Rect *update_rect, - int width) -{ - foo_canvas_request_redraw (canvas, - update_rect->x0, update_rect->y0, - update_rect->x1, update_rect->y0 + width); - foo_canvas_request_redraw (canvas, - update_rect->x0, update_rect->y1-width, - update_rect->x1, update_rect->y1); - foo_canvas_request_redraw (canvas, - update_rect->x0, update_rect->y0, - update_rect->x0+width, update_rect->y1); - foo_canvas_request_redraw (canvas, - update_rect->x1-width, update_rect->y0, - update_rect->x1, update_rect->y1); -} - - -static void -foo_canvas_rect_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, gint flags) -{ - FooCanvasRE *re; - double x1, y1, x2, y2; - int cx1, cy1, cx2, cy2; - int repaint_rects_count, i; - int width_pixels; - int width_lt, width_rb; - Rect update_rect, repaint_rects[4]; - FooCanvasRectPrivate *priv; - - foo_canvas_re_update_shared (item, i2w_dx, i2w_dy, flags); - - re = FOO_CANVAS_RE (item); - priv = FOO_CANVAS_RECT (item)->priv; - - x1 = re->x1 + i2w_dx; - y1 = re->y1 + i2w_dy; - x2 = re->x2 + i2w_dx; - y2 = re->y2 + i2w_dy; - - foo_canvas_w2c (item->canvas, x1, y1, &cx1, &cy1); - foo_canvas_w2c (item->canvas, x2, y2, &cx2, &cy2); - - update_rect = make_rect (cx1, cy1, cx2+1, cy2+1); -#if 0 - foo_canvas_request_redraw (item->canvas, - update_rect.x0, update_rect.y0, - update_rect.x1, update_rect.y1); - foo_canvas_request_redraw (item->canvas, - priv->last_update_rect.x0, priv->last_update_rect.y0, - priv->last_update_rect.x1, priv->last_update_rect.y1); -#else - diff_rects (update_rect, priv->last_update_rect, - &repaint_rects_count, repaint_rects); - for (i = 0; i < repaint_rects_count; i++) { - foo_canvas_request_redraw (item->canvas, - repaint_rects[i].x0, repaint_rects[i].y0, - repaint_rects[i].x1, repaint_rects[i].y1); - } -#endif - priv->last_update_rect = update_rect; - - if (re->outline_set) { - /* Outline and bounding box */ - if (re->width_pixels) - width_pixels = (int) re->width; - else - width_pixels = (int) floor (re->width * re->item.canvas->pixels_per_unit_x + 0.5); - - width_lt = width_pixels / 2; - width_rb = (width_pixels + 1) / 2; - - cx1 -= width_lt; - cy1 -= width_lt; - cx2 += width_rb; - cy2 += width_rb; - - update_rect = make_rect (cx1, cy1, cx2, cy2); - request_redraw_borders (item->canvas, &update_rect, - (width_lt + width_rb)); - request_redraw_borders (item->canvas, &priv->last_outline_update_rect, - priv->last_outline_update_width); - priv->last_outline_update_rect = update_rect; - priv->last_outline_update_width = width_lt + width_rb; - - item->x1 = cx1; - item->y1 = cy1; - item->x2 = cx2+1; - item->y2 = cy2+1; - } else { - item->x1 = cx1; - item->y1 = cy1; - item->x2 = cx2+1; - item->y2 = cy2+1; - } -} - -/* Ellipse item */ - - -static void foo_canvas_ellipse_class_init (FooCanvasEllipseClass *class); - -static void foo_canvas_ellipse_draw (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose); -static double foo_canvas_ellipse_point (FooCanvasItem *item, double x, double y, int cx, int cy, - FooCanvasItem **actual_item); - - -GType -foo_canvas_ellipse_get_type (void) -{ - static GType ellipse_type = 0; - - if (!ellipse_type) { - GTypeInfo ellipse_info = { - sizeof (FooCanvasEllipseClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) foo_canvas_ellipse_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (FooCanvasEllipse), - 0, /* n_preallocs */ - (GInstanceInitFunc) NULL - - }; - - ellipse_type = g_type_register_static (foo_canvas_re_get_type (), - "FooCanvasEllipse", - &ellipse_info, - 0); - } - - return ellipse_type; -} - -static void -foo_canvas_ellipse_class_init (FooCanvasEllipseClass *class) -{ - FooCanvasItemClass *item_class; - - item_class = (FooCanvasItemClass *) class; - - item_class->draw = foo_canvas_ellipse_draw; - item_class->point = foo_canvas_ellipse_point; - item_class->update = foo_canvas_ellipse_update; -} - -static void -foo_canvas_ellipse_draw (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose) -{ - FooCanvasRE *re; - int x1, y1, x2, y2; - double i2w_dx, i2w_dy; - - re = FOO_CANVAS_RE (item); - - /* Get canvas pixel coordinates */ - - i2w_dx = 0.0; - i2w_dy = 0.0; - foo_canvas_item_i2w (item, &i2w_dx, &i2w_dy); - - foo_canvas_w2c (item->canvas, - re->x1 + i2w_dx, - re->y1 + i2w_dy, - &x1, &y1); - foo_canvas_w2c (item->canvas, - re->x2 + i2w_dx, - re->y2 + i2w_dy, - &x2, &y2); - - if (re->fill_set) { - if (re->fill_stipple) - foo_canvas_set_stipple_origin (item->canvas, re->fill_gc); - - gdk_draw_arc (drawable, - re->fill_gc, - TRUE, - x1, - y1, - x2 - x1, - y2 - y1, - 0 * 64, - 360 * 64); - } - - if (re->outline_set) { - if (re->outline_stipple) - foo_canvas_set_stipple_origin (item->canvas, re->outline_gc); - - gdk_draw_arc (drawable, - re->outline_gc, - FALSE, - x1, - y1, - x2 - x1, - y2 - y1, - 0 * 64, - 360 * 64); - } -} - -static double -foo_canvas_ellipse_point (FooCanvasItem *item, double x, double y, int cx, int cy, FooCanvasItem **actual_item) -{ - FooCanvasRE *re; - double dx, dy; - double scaled_dist; - double outline_dist; - double center_dist; - double width; - double a, b; - double diamx, diamy; - - re = FOO_CANVAS_RE (item); - - *actual_item = item; - - if (re->outline_set) { - if (re->width_pixels) - width = re->width / item->canvas->pixels_per_unit_x; - else - width = re->width; - } else - width = 0.0; - - /* Compute the distance between the center of the ellipse and the point, with the ellipse - * considered as being scaled to a circle. - */ - - dx = x - (re->x1 + re->x2) / 2.0; - dy = y - (re->y1 + re->y2) / 2.0; - center_dist = sqrt (dx * dx + dy * dy); - - a = dx / ((re->x2 + width - re->x1) / 2.0); - b = dy / ((re->y2 + width - re->y1) / 2.0); - scaled_dist = sqrt (a * a + b * b); - - /* If the scaled distance is greater than 1, then we are outside. Compute the distance from - * the point to the edge of the circle, then scale back to the original un-scaled coordinate - * system. - */ - - if (scaled_dist > 1.0) - return (center_dist / scaled_dist) * (scaled_dist - 1.0); - - /* We are inside the outer edge of the ellipse. If it is filled, then we are "inside". - * Otherwise, do the same computation as above, but also check whether we are inside the - * outline. - */ - - if (re->fill_set) - return 0.0; - - if (scaled_dist > FOO_CANVAS_EPSILON) - outline_dist = (center_dist / scaled_dist) * (1.0 - scaled_dist) - width; - else { - /* Handle very small distance */ - - diamx = re->x2 - re->x1; - diamy = re->y2 - re->y1; - - if (diamx < diamy) - outline_dist = (diamx - width) / 2.0; - else - outline_dist = (diamy - width) / 2.0; - } - - if (outline_dist < 0.0) - return 0.0; - - return outline_dist; -} - -static void -foo_canvas_ellipse_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, gint flags) -{ - FooCanvasRE *re; - double x0, y0, x1, y1; - -#ifdef VERBOSE - g_print ("foo_canvas_sllipse_update item %x\n", item); -#endif - - foo_canvas_re_update_shared (item, i2w_dx, i2w_dy, flags); - re = FOO_CANVAS_RE (item); - - get_bounds (re, &x0, &y0, &x1, &y1); - foo_canvas_update_bbox (item, x0, y0, x1, y1); -} - -static int -rect_empty (const Rect *src) { - return (src->x1 <= src->x0 || src->y1 <= src->y0); -} - -static Rect -make_rect (int x0, int y0, int x1, int y1) -{ - Rect r; - - r.x0 = x0; - r.y0 = y0; - r.x1 = x1; - r.y1 = y1; - return r; -} - -static gboolean -rects_intersect (Rect r1, Rect r2) -{ - if (r1.x0 >= r2.x1) { - return FALSE; - } - if (r2.x0 >= r1.x1) { - return FALSE; - } - if (r1.y0 >= r2.y1) { - return FALSE; - } - if (r2.y0 >= r1.y1) { - return FALSE; - } - return TRUE; -} - -static void -diff_rects_guts (Rect ra, Rect rb, int *count, Rect result[4]) -{ - if (ra.x0 < rb.x0) { - result[(*count)++] = make_rect (ra.x0, ra.y0, rb.x0, ra.y1); - } - if (ra.y0 < rb.y0) { - result[(*count)++] = make_rect (ra.x0, ra.y0, ra.x1, rb.y0); - } - if (ra.x1 < rb.x1) { - result[(*count)++] = make_rect (ra.x1, rb.y0, rb.x1, rb.y1); - } - if (ra.y1 < rb.y1) { - result[(*count)++] = make_rect (rb.x0, ra.y1, rb.x1, rb.y1); - } -} - -static void -diff_rects (Rect r1, Rect r2, int *count, Rect result[4]) -{ - g_assert (count != NULL); - g_assert (result != NULL); - - *count = 0; - - if (rects_intersect (r1, r2)) { - diff_rects_guts (r1, r2, count, result); - diff_rects_guts (r2, r1, count, result); - } else { - if (!rect_empty (&r1)) { - result[(*count)++] = r1; - } - if (!rect_empty (&r2)) { - result[(*count)++] = r2; - } - } -} diff --git a/foocanvas/foo-canvas-text.c b/foocanvas/foo-canvas-text.c deleted file mode 100755 index 1a385f41d..000000000 --- a/foocanvas/foo-canvas-text.c +++ /dev/null @@ -1,1623 +0,0 @@ -/* Last edited: May 11 11:41 2004 (rnc) */ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * $Id: foo-canvas-text.c,v 1.1 2004-05-13 14:36:25 rnc Exp $ - * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation - * All rights reserved. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with the Gnome Library; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -/* - @NOTATION@ - */ -/* Text item type for FooCanvas widget - * - * FooCanvas is basically a port of the Tk toolkit's most excellent canvas - * widget. Tk is copyrighted by the Regents of the University of California, - * Sun Microsystems, and other parties. - * - * - * Author: Federico Mena <federico@nuclecu.unam.mx> - * Port to Pango co-done by Gergõ Érdi <cactus@cactus.rulez.org> - */ - -#include <config.h> -#include <math.h> -#include <string.h> -#include "foo-canvas-text.h" - -#include "foo-canvas-util.h" -#include "foo-canvas-i18n.h" - - - -/* Object argument IDs */ -enum { - PROP_0, - - /* Text contents */ - PROP_TEXT, - PROP_MARKUP, - - /* Position */ - PROP_X, - PROP_Y, - - /* Font */ - PROP_FONT, - PROP_FONT_DESC, - PROP_FAMILY, PROP_FAMILY_SET, - - /* Style */ - PROP_ATTRIBUTES, - PROP_STYLE, PROP_STYLE_SET, - PROP_VARIANT, PROP_VARIANT_SET, - PROP_WEIGHT, PROP_WEIGHT_SET, - PROP_STRETCH, PROP_STRETCH_SET, - PROP_SIZE, PROP_SIZE_SET, - PROP_SIZE_POINTS, - PROP_STRIKETHROUGH, PROP_STRIKETHROUGH_SET, - PROP_UNDERLINE, PROP_UNDERLINE_SET, - PROP_RISE, PROP_RISE_SET, - PROP_SCALE, PROP_SCALE_SET, - - /* Clipping */ - PROP_ANCHOR, - PROP_JUSTIFICATION, - PROP_CLIP_WIDTH, - PROP_CLIP_HEIGHT, - PROP_CLIP, - PROP_WRAP_WIDTH, - PROP_X_OFFSET, - PROP_Y_OFFSET, - - /* Coloring */ - PROP_FILL_COLOR, - PROP_FILL_COLOR_GDK, - PROP_FILL_COLOR_RGBA, - PROP_FILL_STIPPLE, - - /* Rendered size accessors */ - PROP_TEXT_WIDTH, - PROP_TEXT_HEIGHT -}; - -struct _FooCanvasTextPrivate { - gint placeholder; -}; - -static void foo_canvas_text_class_init (FooCanvasTextClass *class); -static void foo_canvas_text_init (FooCanvasText *text); -static void foo_canvas_text_destroy (GtkObject *object); -static void foo_canvas_text_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec); -static void foo_canvas_text_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec); - -static void foo_canvas_text_update (FooCanvasItem *item, - double i2w_dx, - double i2w_dy, - int flags); -static void foo_canvas_text_realize (FooCanvasItem *item); -static void foo_canvas_text_unrealize (FooCanvasItem *item); -static void foo_canvas_text_draw (FooCanvasItem *item, - GdkDrawable *drawable, - GdkEventExpose *expose); -static double foo_canvas_text_point (FooCanvasItem *item, - double x, - double y, - int cx, - int cy, - FooCanvasItem **actual_item); -static void foo_canvas_text_translate (FooCanvasItem *item, - double dx, - double dy); -static void foo_canvas_text_bounds (FooCanvasItem *item, - double *x1, - double *y1, - double *x2, - double *y2); - -static void foo_canvas_text_set_markup (FooCanvasText *textitem, - const gchar *markup); - -static void foo_canvas_text_set_font_desc (FooCanvasText *textitem, - PangoFontDescription *font_desc); - -static void foo_canvas_text_apply_font_desc (FooCanvasText *textitem); -static void foo_canvas_text_apply_attributes (FooCanvasText *textitem); - -static void add_attr (PangoAttrList *attr_list, - PangoAttribute *attr); - -static FooCanvasItemClass *parent_class; - - - -/** - * foo_canvas_text_get_type: - * @void: - * - * Registers the &FooCanvasText class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &FooCanvasText class. - **/ -GtkType -foo_canvas_text_get_type (void) -{ - static GtkType text_type = 0; - - if (!text_type) { - /* FIXME: Convert to gobject style. */ - static const GtkTypeInfo text_info = { - (char *)"FooCanvasText", - sizeof (FooCanvasText), - sizeof (FooCanvasTextClass), - (GtkClassInitFunc) foo_canvas_text_class_init, - (GtkObjectInitFunc) foo_canvas_text_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - text_type = gtk_type_unique (foo_canvas_item_get_type (), &text_info); - } - - return text_type; -} - -/* Class initialization function for the text item */ -static void -foo_canvas_text_class_init (FooCanvasTextClass *class) -{ - GObjectClass *gobject_class; - GtkObjectClass *object_class; - FooCanvasItemClass *item_class; - - gobject_class = (GObjectClass *) class; - object_class = (GtkObjectClass *) class; - item_class = (FooCanvasItemClass *) class; - - parent_class = gtk_type_class (foo_canvas_item_get_type ()); - - gobject_class->set_property = foo_canvas_text_set_property; - gobject_class->get_property = foo_canvas_text_get_property; - - /* Text */ - g_object_class_install_property - (gobject_class, - PROP_TEXT, - g_param_spec_string ("text", - _("Text"), - _("Text to render"), - NULL, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - - g_object_class_install_property - (gobject_class, - PROP_MARKUP, - g_param_spec_string ("markup", - _("Markup"), - _("Marked up text to render"), - NULL, - (G_PARAM_WRITABLE))); - - /* Position */ - g_object_class_install_property - (gobject_class, - PROP_X, - g_param_spec_double ("x", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - - g_object_class_install_property - (gobject_class, - PROP_Y, - g_param_spec_double ("y", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - - - /* Font */ - g_object_class_install_property - (gobject_class, - PROP_FONT, - g_param_spec_string ("font", - _("Font"), - _("Font description as a string"), - NULL, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - - g_object_class_install_property - (gobject_class, - PROP_FONT_DESC, - g_param_spec_boxed ("font_desc", - _("Font description"), - _("Font description as a PangoFontDescription struct"), - PANGO_TYPE_FONT_DESCRIPTION, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - - g_object_class_install_property - (gobject_class, - PROP_FAMILY, - g_param_spec_string ("family", - _("Font family"), - _("Name of the font family, e.g. Sans, Helvetica, Times, Monospace"), - NULL, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - - /* Style */ - g_object_class_install_property - (gobject_class, - PROP_ATTRIBUTES, - g_param_spec_boxed ("attributes", NULL, NULL, - PANGO_TYPE_ATTR_LIST, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - - g_object_class_install_property - (gobject_class, - PROP_STYLE, - g_param_spec_enum ("style", - _("Font style"), - _("Font style"), - PANGO_TYPE_STYLE, - PANGO_STYLE_NORMAL, - G_PARAM_READABLE | G_PARAM_WRITABLE)); - - g_object_class_install_property - (gobject_class, - PROP_VARIANT, - g_param_spec_enum ("variant", - _("Font variant"), - _("Font variant"), - PANGO_TYPE_VARIANT, - PANGO_VARIANT_NORMAL, - G_PARAM_READABLE | G_PARAM_WRITABLE)); - - g_object_class_install_property - (gobject_class, - PROP_WEIGHT, - g_param_spec_int ("weight", - _("Font weight"), - _("Font weight"), - 0, - G_MAXINT, - PANGO_WEIGHT_NORMAL, - G_PARAM_READABLE | G_PARAM_WRITABLE)); - - - g_object_class_install_property - (gobject_class, - PROP_STRETCH, - g_param_spec_enum ("stretch", - _("Font stretch"), - _("Font stretch"), - PANGO_TYPE_STRETCH, - PANGO_STRETCH_NORMAL, - G_PARAM_READABLE | G_PARAM_WRITABLE)); - - g_object_class_install_property - (gobject_class, - PROP_SIZE, - g_param_spec_int ("size", - _("Font size"), - _("Font size"), - 0, - G_MAXINT, - 0, - G_PARAM_READABLE | G_PARAM_WRITABLE)); - - g_object_class_install_property - (gobject_class, - PROP_SIZE_POINTS, - g_param_spec_double ("size_points", - _("Font points"), - _("Font size in points"), - 0.0, - G_MAXDOUBLE, - 0.0, - G_PARAM_READABLE | G_PARAM_WRITABLE)); - - g_object_class_install_property - (gobject_class, - PROP_RISE, - g_param_spec_int ("rise", - _("Rise"), - _("Offset of text above the baseline (below the baseline if rise is negative)"), - -G_MAXINT, - G_MAXINT, - 0, - G_PARAM_READABLE | G_PARAM_WRITABLE)); - - g_object_class_install_property - (gobject_class, - PROP_STRIKETHROUGH, - g_param_spec_boolean ("strikethrough", - _("Strikethrough"), - _("Whether to strike through the text"), - FALSE, - G_PARAM_READABLE | G_PARAM_WRITABLE)); - - g_object_class_install_property - (gobject_class, - PROP_UNDERLINE, - g_param_spec_enum ("underline", - _("Underline"), - _("Style of underline for this text"), - PANGO_TYPE_UNDERLINE, - PANGO_UNDERLINE_NONE, - G_PARAM_READABLE | G_PARAM_WRITABLE)); - - g_object_class_install_property - (gobject_class, - PROP_SCALE, - g_param_spec_double ("scale", - _("Scale"), - _("Size of font, relative to default size"), - 0.0, - G_MAXDOUBLE, - 1.0, - G_PARAM_READABLE | G_PARAM_WRITABLE)); - - g_object_class_install_property - (gobject_class, - PROP_ANCHOR, - g_param_spec_enum ("anchor", NULL, NULL, - GTK_TYPE_ANCHOR_TYPE, - GTK_ANCHOR_CENTER, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_JUSTIFICATION, - g_param_spec_enum ("justification", NULL, NULL, - GTK_TYPE_JUSTIFICATION, - GTK_JUSTIFY_LEFT, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_CLIP_WIDTH, - g_param_spec_double ("clip_width", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_CLIP_HEIGHT, - g_param_spec_double ("clip_height", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_CLIP, - g_param_spec_boolean ("clip", NULL, NULL, - FALSE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_WRAP_WIDTH, - g_param_spec_double ("wrap_width", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_X_OFFSET, - g_param_spec_double ("x_offset", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_Y_OFFSET, - g_param_spec_double ("y_offset", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FILL_COLOR, - g_param_spec_string ("fill_color", - _("Color"), - _("Text color, as string"), - NULL, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FILL_COLOR_GDK, - g_param_spec_boxed ("fill_color_gdk", - _("Color"), - _("Text color, as a GdkColor"), - GDK_TYPE_COLOR, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FILL_COLOR_RGBA, - g_param_spec_uint ("fill_color_rgba", - _("Color"), - _("Text color, as an R/G/B/A combined integer"), - 0, G_MAXUINT, 0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_FILL_STIPPLE, - g_param_spec_object ("fill_stipple", NULL, NULL, - GDK_TYPE_DRAWABLE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_TEXT_WIDTH, - g_param_spec_double ("text_width", - _("Text width"), - _("Width of the rendered text"), - 0.0, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_TEXT_HEIGHT, - g_param_spec_double ("text_height", - _("Text height"), - _("Height of the rendered text"), - 0.0, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - - /* Style props are set (explicitly applied) or not */ -#define ADD_SET_PROP(propname, propval, nick, blurb) g_object_class_install_property (gobject_class, propval, g_param_spec_boolean (propname, nick, blurb, FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE)) - - ADD_SET_PROP ("family_set", PROP_FAMILY_SET, - _("Font family set"), - _("Whether this tag affects the font family")); - - ADD_SET_PROP ("style_set", PROP_STYLE_SET, - _("Font style set"), - _("Whether this tag affects the font style")); - - ADD_SET_PROP ("variant_set", PROP_VARIANT_SET, - _("Font variant set"), - _("Whether this tag affects the font variant")); - - ADD_SET_PROP ("weight_set", PROP_WEIGHT_SET, - _("Font weight set"), - _("Whether this tag affects the font weight")); - - ADD_SET_PROP ("stretch_set", PROP_STRETCH_SET, - _("Font stretch set"), - _("Whether this tag affects the font stretch")); - - ADD_SET_PROP ("size_set", PROP_SIZE_SET, - _("Font size set"), - _("Whether this tag affects the font size")); - - ADD_SET_PROP ("rise_set", PROP_RISE_SET, - _("Rise set"), - _("Whether this tag affects the rise")); - - ADD_SET_PROP ("strikethrough_set", PROP_STRIKETHROUGH_SET, - _("Strikethrough set"), - _("Whether this tag affects strikethrough")); - - ADD_SET_PROP ("underline_set", PROP_UNDERLINE_SET, - _("Underline set"), - _("Whether this tag affects underlining")); - - ADD_SET_PROP ("scale_set", PROP_SCALE_SET, - _("Scale set"), - _("Whether this tag affects font scaling")); -#undef ADD_SET_PROP - - object_class->destroy = foo_canvas_text_destroy; - - item_class->update = foo_canvas_text_update; - item_class->realize = foo_canvas_text_realize; - item_class->unrealize = foo_canvas_text_unrealize; - item_class->draw = foo_canvas_text_draw; - item_class->point = foo_canvas_text_point; - item_class->translate = foo_canvas_text_translate; - item_class->bounds = foo_canvas_text_bounds; -} - -/* Object initialization function for the text item */ -static void -foo_canvas_text_init (FooCanvasText *text) -{ - text->x = 0.0; - text->y = 0.0; - text->anchor = GTK_ANCHOR_CENTER; - text->justification = GTK_JUSTIFY_LEFT; - text->clip_width = 0.0; - text->clip_height = 0.0; - text->xofs = 0.0; - text->yofs = 0.0; - text->layout = NULL; - - text->font_desc = NULL; - - text->underline = PANGO_UNDERLINE_NONE; - text->strikethrough = FALSE; - text->rise = 0; - - text->underline_set = FALSE; - text->strike_set = FALSE; - text->rise_set = FALSE; - - text->priv = g_new (FooCanvasTextPrivate, 1); -} - -/* Destroy handler for the text item */ -static void -foo_canvas_text_destroy (GtkObject *object) -{ - FooCanvasText *text; - - g_return_if_fail (FOO_IS_CANVAS_TEXT (object)); - - text = FOO_CANVAS_TEXT (object); - - /* remember, destroy can be run multiple times! */ - - g_free (text->text); - text->text = NULL; - - if (text->layout) - g_object_unref (G_OBJECT (text->layout)); - text->layout = NULL; - - if (text->font_desc) { - pango_font_description_free (text->font_desc); - text->font_desc = NULL; - } - - if (text->attr_list) - pango_attr_list_unref (text->attr_list); - text->attr_list = NULL; - - if (text->stipple) - g_object_unref (text->stipple); - text->stipple = NULL; - - g_free (text->priv); - text->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -static void -get_bounds (FooCanvasText *text, double *px1, double *py1, double *px2, double *py2) -{ - FooCanvasItem *item; - double wx, wy; - - item = FOO_CANVAS_ITEM (text); - - /* Get canvas pixel coordinates for text position */ - - - wx = text->x; - wy = text->y; - foo_canvas_item_i2w (item, &wx, &wy); - foo_canvas_w2c (item->canvas, wx + text->xofs, wy + text->yofs, &text->cx, &text->cy); - - /* Get canvas pixel coordinates for clip rectangle position */ - - foo_canvas_w2c (item->canvas, wx, wy, &text->clip_cx, &text->clip_cy); - text->clip_cwidth = text->clip_width * item->canvas->pixels_per_unit_x; - text->clip_cheight = text->clip_height * item->canvas->pixels_per_unit_y; - - /* Anchor text */ - - switch (text->anchor) { - case GTK_ANCHOR_NW: - case GTK_ANCHOR_W: - case GTK_ANCHOR_SW: - break; - - case GTK_ANCHOR_N: - case GTK_ANCHOR_CENTER: - case GTK_ANCHOR_S: - text->cx -= text->max_width / 2; - text->clip_cx -= text->clip_cwidth / 2; - break; - - case GTK_ANCHOR_NE: - case GTK_ANCHOR_E: - case GTK_ANCHOR_SE: - text->cx -= text->max_width; - text->clip_cx -= text->clip_cwidth; - break; - - default: - break; - } - - switch (text->anchor) { - case GTK_ANCHOR_NW: - case GTK_ANCHOR_N: - case GTK_ANCHOR_NE: - break; - - case GTK_ANCHOR_W: - case GTK_ANCHOR_CENTER: - case GTK_ANCHOR_E: - text->cy -= text->height / 2; - text->clip_cy -= text->clip_cheight / 2; - break; - - case GTK_ANCHOR_SW: - case GTK_ANCHOR_S: - case GTK_ANCHOR_SE: - text->cy -= text->height; - text->clip_cy -= text->clip_cheight; - break; - - default: - break; - } - - /* Bounds */ - - if (text->clip) { - *px1 = text->clip_cx; - *py1 = text->clip_cy; - *px2 = text->clip_cx + text->clip_cwidth; - *py2 = text->clip_cy + text->clip_cheight; - } else { - *px1 = text->cx; - *py1 = text->cy; - *px2 = text->cx + text->max_width; - *py2 = text->cy + text->height; - } -} - -/* Convenience function to set the text's GC's foreground color */ -static void -set_text_gc_foreground (FooCanvasText *text) -{ - GdkColor c; - - if (!text->gc) - return; - - c.pixel = text->pixel; - gdk_gc_set_foreground (text->gc, &c); -} - -/* Sets the stipple pattern for the text */ -static void -set_stipple (FooCanvasText *text, GdkBitmap *stipple, int reconfigure) -{ - if (text->stipple && !reconfigure) - g_object_unref (text->stipple); - - text->stipple = stipple; - if (stipple && !reconfigure) - g_object_ref (stipple); - - if (text->gc) { - if (stipple) { - gdk_gc_set_stipple (text->gc, stipple); - gdk_gc_set_fill (text->gc, GDK_STIPPLED); - } else - gdk_gc_set_fill (text->gc, GDK_SOLID); - } -} - -static PangoFontMask -get_property_font_set_mask (guint prop_id) -{ - switch (prop_id) - { - case PROP_FAMILY_SET: - return PANGO_FONT_MASK_FAMILY; - case PROP_STYLE_SET: - return PANGO_FONT_MASK_STYLE; - case PROP_VARIANT_SET: - return PANGO_FONT_MASK_VARIANT; - case PROP_WEIGHT_SET: - return PANGO_FONT_MASK_WEIGHT; - case PROP_STRETCH_SET: - return PANGO_FONT_MASK_STRETCH; - case PROP_SIZE_SET: - return PANGO_FONT_MASK_SIZE; - } - - return 0; -} - -static void -ensure_font (FooCanvasText *text) -{ - if (!text->font_desc) - text->font_desc = pango_font_description_new (); -} - -/* Set_arg handler for the text item */ -static void -foo_canvas_text_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) -{ - FooCanvasItem *item; - FooCanvasText *text; - GdkColor color = { 0, 0, 0, 0, }; - GdkColor *pcolor; - gboolean color_changed; - int have_pixel; - PangoAlignment align; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_TEXT (object)); - - item = FOO_CANVAS_ITEM (object); - text = FOO_CANVAS_TEXT (object); - - color_changed = FALSE; - have_pixel = FALSE; - - - if (!text->layout) { - text->layout = gtk_widget_create_pango_layout (GTK_WIDGET (item->canvas), NULL); - } - - switch (param_id) { - case PROP_TEXT: - if (text->text) - g_free (text->text); - - text->text = g_value_dup_string (value); - pango_layout_set_text (text->layout, text->text, -1); - - break; - - case PROP_MARKUP: - foo_canvas_text_set_markup (text, - g_value_get_string (value)); - break; - - case PROP_X: - text->x = g_value_get_double (value); - break; - - case PROP_Y: - text->y = g_value_get_double (value); - break; - - case PROP_FONT: { - const char *font_name; - PangoFontDescription *font_desc; - - font_name = g_value_get_string (value); - if (font_name) - font_desc = pango_font_description_from_string (font_name); - else - font_desc = NULL; - - foo_canvas_text_set_font_desc (text, font_desc); - if (font_desc) - pango_font_description_free (font_desc); - - break; - } - - case PROP_FONT_DESC: - foo_canvas_text_set_font_desc (text, g_value_peek_pointer (value)); - break; - - case PROP_FAMILY: - case PROP_STYLE: - case PROP_VARIANT: - case PROP_WEIGHT: - case PROP_STRETCH: - case PROP_SIZE: - case PROP_SIZE_POINTS: - ensure_font (text); - - switch (param_id) { - case PROP_FAMILY: - pango_font_description_set_family (text->font_desc, - g_value_get_string (value)); - break; - case PROP_STYLE: - pango_font_description_set_style (text->font_desc, - g_value_get_enum (value)); - break; - case PROP_VARIANT: - pango_font_description_set_variant (text->font_desc, - g_value_get_enum (value)); - break; - case PROP_WEIGHT: - pango_font_description_set_weight (text->font_desc, - g_value_get_int (value)); - break; - case PROP_STRETCH: - pango_font_description_set_stretch (text->font_desc, - g_value_get_enum (value)); - break; - case PROP_SIZE: - /* FIXME: This is bogus! It should be pixels, not points/PANGO_SCALE! */ - pango_font_description_set_size (text->font_desc, - g_value_get_int (value)); - break; - case PROP_SIZE_POINTS: - pango_font_description_set_size (text->font_desc, - g_value_get_double (value) * PANGO_SCALE); - break; - } - - foo_canvas_text_apply_font_desc (text); - break; - - case PROP_FAMILY_SET: - case PROP_STYLE_SET: - case PROP_VARIANT_SET: - case PROP_WEIGHT_SET: - case PROP_STRETCH_SET: - case PROP_SIZE_SET: - if (!g_value_get_boolean (value) && text->font_desc) - pango_font_description_unset_fields (text->font_desc, - get_property_font_set_mask (param_id)); - break; - - case PROP_SCALE: - text->scale = g_value_get_double (value); - text->scale_set = TRUE; - - foo_canvas_text_apply_font_desc (text); - break; - - case PROP_SCALE_SET: - text->scale_set = g_value_get_boolean (value); - - foo_canvas_text_apply_font_desc (text); - break; - - case PROP_UNDERLINE: - text->underline = g_value_get_enum (value); - text->underline_set = TRUE; - - foo_canvas_text_apply_attributes (text); - break; - - case PROP_UNDERLINE_SET: - text->underline_set = g_value_get_boolean (value); - - foo_canvas_text_apply_attributes (text); - break; - - case PROP_STRIKETHROUGH: - text->strikethrough = g_value_get_boolean (value); - text->strike_set = TRUE; - - foo_canvas_text_apply_attributes (text); - break; - - case PROP_STRIKETHROUGH_SET: - text->strike_set = g_value_get_boolean (value); - - foo_canvas_text_apply_attributes (text); - break; - - case PROP_RISE: - text->rise = g_value_get_int (value); - text->rise_set = TRUE; - - foo_canvas_text_apply_attributes (text); - break; - - case PROP_RISE_SET: - text->rise_set = TRUE; - - foo_canvas_text_apply_attributes (text); - break; - - case PROP_ATTRIBUTES: - if (text->attr_list) - pango_attr_list_unref (text->attr_list); - - text->attr_list = g_value_peek_pointer (value); - if (text->attr_list) - pango_attr_list_ref (text->attr_list); - - foo_canvas_text_apply_attributes (text); - break; - - case PROP_ANCHOR: - text->anchor = g_value_get_enum (value); - break; - - case PROP_JUSTIFICATION: - text->justification = g_value_get_enum (value); - - switch (text->justification) { - case GTK_JUSTIFY_LEFT: - align = PANGO_ALIGN_LEFT; - break; - case GTK_JUSTIFY_CENTER: - align = PANGO_ALIGN_CENTER; - break; - case GTK_JUSTIFY_RIGHT: - align = PANGO_ALIGN_RIGHT; - break; - default: - /* GTK_JUSTIFY_FILL isn't supported yet. */ - align = PANGO_ALIGN_LEFT; - break; - } - pango_layout_set_alignment (text->layout, align); - break; - - case PROP_CLIP_WIDTH: - text->clip_width = fabs (g_value_get_double (value)); - break; - - case PROP_CLIP_HEIGHT: - text->clip_height = fabs (g_value_get_double (value)); - break; - - case PROP_CLIP: - text->clip = g_value_get_boolean (value); - break; - - case PROP_WRAP_WIDTH: { - double w = fabs (g_value_get_double (value)); - pango_layout_set_width (text->layout, - w * text->item.canvas->pixels_per_unit_x * PANGO_SCALE); - - break; - } - - case PROP_X_OFFSET: - text->xofs = g_value_get_double (value); - break; - - case PROP_Y_OFFSET: - text->yofs = g_value_get_double (value); - break; - - case PROP_FILL_COLOR: { - const char *color_name; - - color_name = g_value_get_string (value); - if (color_name) { - gdk_color_parse (color_name, &color); - - text->rgba = ((color.red & 0xff00) << 16 | - (color.green & 0xff00) << 8 | - (color.blue & 0xff00) | - 0xff); - color_changed = TRUE; - } - break; - } - - case PROP_FILL_COLOR_GDK: - pcolor = g_value_get_boxed (value); - if (pcolor) { - GdkColormap *colormap; - - color = *pcolor; - colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); - gdk_rgb_find_color (colormap, &color); - have_pixel = TRUE; - } - - text->rgba = ((color.red & 0xff00) << 16 | - (color.green & 0xff00) << 8| - (color.blue & 0xff00) | - 0xff); - color_changed = TRUE; - break; - - case PROP_FILL_COLOR_RGBA: - text->rgba = g_value_get_uint (value); - color_changed = TRUE; - break; - - case PROP_FILL_STIPPLE: - set_stipple (text, (GdkBitmap *)g_value_get_object (value), FALSE); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } - - if (color_changed) { - if (have_pixel) - text->pixel = color.pixel; - else - text->pixel = foo_canvas_get_color_pixel (item->canvas, text->rgba); - - set_text_gc_foreground (text); - } - - /* Calculate text dimensions */ - - if (text->layout) - pango_layout_get_pixel_size (text->layout, - &text->max_width, - &text->height); - else { - text->max_width = 0; - text->height = 0; - } - - foo_canvas_item_request_update (item); -} - -/* Get_arg handler for the text item */ -static void -foo_canvas_text_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec) -{ - FooCanvasText *text; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_TEXT (object)); - - text = FOO_CANVAS_TEXT (object); - - switch (param_id) { - case PROP_TEXT: - g_value_set_string (value, text->text); - break; - - case PROP_X: - g_value_set_double (value, text->x); - break; - - case PROP_Y: - g_value_set_double (value, text->y); - break; - - case PROP_FONT: - case PROP_FONT_DESC: - case PROP_FAMILY: - case PROP_STYLE: - case PROP_VARIANT: - case PROP_WEIGHT: - case PROP_STRETCH: - case PROP_SIZE: - case PROP_SIZE_POINTS: - ensure_font (text); - - switch (param_id) { - case PROP_FONT: - { - /* FIXME GValue imposes a totally gratuitous string copy - * here, we could just hand off string ownership - */ - gchar *str; - - str = pango_font_description_to_string (text->font_desc); - g_value_set_string (value, str); - g_free (str); - - break; - } - - case PROP_FONT_DESC: - g_value_set_boxed (value, text->font_desc); - break; - - case PROP_FAMILY: - g_value_set_string (value, pango_font_description_get_family (text->font_desc)); - break; - - case PROP_STYLE: - g_value_set_enum (value, pango_font_description_get_style (text->font_desc)); - break; - - case PROP_VARIANT: - g_value_set_enum (value, pango_font_description_get_variant (text->font_desc)); - break; - - case PROP_WEIGHT: - g_value_set_int (value, pango_font_description_get_weight (text->font_desc)); - break; - - case PROP_STRETCH: - g_value_set_enum (value, pango_font_description_get_stretch (text->font_desc)); - break; - - case PROP_SIZE: - g_value_set_int (value, pango_font_description_get_size (text->font_desc)); - break; - - case PROP_SIZE_POINTS: - g_value_set_double (value, ((double)pango_font_description_get_size (text->font_desc)) / (double)PANGO_SCALE); - break; - } - break; - - case PROP_FAMILY_SET: - case PROP_STYLE_SET: - case PROP_VARIANT_SET: - case PROP_WEIGHT_SET: - case PROP_STRETCH_SET: - case PROP_SIZE_SET: - { - PangoFontMask set_mask = text->font_desc ? pango_font_description_get_set_fields (text->font_desc) : 0; - PangoFontMask test_mask = get_property_font_set_mask (param_id); - g_value_set_boolean (value, (set_mask & test_mask) != 0); - - break; - } - - case PROP_SCALE: - g_value_set_double (value, text->scale); - break; - case PROP_SCALE_SET: - g_value_set_boolean (value, text->scale_set); - break; - - case PROP_UNDERLINE: - g_value_set_enum (value, text->underline); - break; - case PROP_UNDERLINE_SET: - g_value_set_boolean (value, text->underline_set); - break; - - case PROP_STRIKETHROUGH: - g_value_set_boolean (value, text->strikethrough); - break; - case PROP_STRIKETHROUGH_SET: - g_value_set_boolean (value, text->strike_set); - break; - - case PROP_RISE: - g_value_set_int (value, text->rise); - break; - case PROP_RISE_SET: - g_value_set_boolean (value, text->rise_set); - break; - - case PROP_ATTRIBUTES: - g_value_set_boxed (value, text->attr_list); - break; - - case PROP_ANCHOR: - g_value_set_enum (value, text->anchor); - break; - - case PROP_JUSTIFICATION: - g_value_set_enum (value, text->justification); - break; - - case PROP_CLIP_WIDTH: - g_value_set_double (value, text->clip_width); - break; - - case PROP_CLIP_HEIGHT: - g_value_set_double (value, text->clip_height); - break; - - case PROP_CLIP: - g_value_set_boolean (value, text->clip); - break; - - case PROP_WRAP_WIDTH: - g_value_set_double (value, - pango_layout_get_width (text->layout) / PANGO_SCALE); - break; - - case PROP_X_OFFSET: - g_value_set_double (value, text->xofs); - break; - - case PROP_Y_OFFSET: - g_value_set_double (value, text->yofs); - break; - - case PROP_FILL_COLOR: - //g_value_take_string (value, - // g_strdup_printf ("#%02x%02x%02x", - // text->rgba >> 24, - // (text->rgba >> 16) & 0xff, - // (text->rgba >> 8) & 0xff)); - break; - - case PROP_FILL_COLOR_GDK: { - FooCanvas *canvas = FOO_CANVAS_ITEM (text)->canvas; - GdkColormap *colormap = gtk_widget_get_colormap (GTK_WIDGET (canvas)); - GdkColor color; - - gdk_colormap_query_color (colormap, text->pixel, &color); - g_value_set_boxed (value, &color); - break; - } - case PROP_FILL_COLOR_RGBA: - g_value_set_uint (value, text->rgba); - break; - - case PROP_FILL_STIPPLE: - g_value_set_object (value, text->stipple); - break; - - case PROP_TEXT_WIDTH: - g_value_set_double (value, text->max_width / text->item.canvas->pixels_per_unit_x); - break; - - case PROP_TEXT_HEIGHT: - g_value_set_double (value, text->height / text->item.canvas->pixels_per_unit_y); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -/* */ -static void -foo_canvas_text_apply_font_desc (FooCanvasText *text) -{ - PangoFontDescription *font_desc = - pango_font_description_copy ( - GTK_WIDGET (FOO_CANVAS_ITEM (text)->canvas)->style->font_desc); - - if (text->font_desc) - pango_font_description_merge (font_desc, text->font_desc, TRUE); - - pango_layout_set_font_description (text->layout, font_desc); - pango_font_description_free (font_desc); -} - -static void -add_attr (PangoAttrList *attr_list, - PangoAttribute *attr) -{ - attr->start_index = 0; - attr->end_index = G_MAXINT; - - pango_attr_list_insert (attr_list, attr); -} - -/* */ -static void -foo_canvas_text_apply_attributes (FooCanvasText *text) -{ - PangoAttrList *attr_list; - double zoom; - - if (text->attr_list) - attr_list = pango_attr_list_copy (text->attr_list); - else - attr_list = pango_attr_list_new (); - - if (text->underline_set) - add_attr (attr_list, pango_attr_underline_new (text->underline)); - if (text->strike_set) - add_attr (attr_list, pango_attr_strikethrough_new (text->strikethrough)); - if (text->rise_set) - add_attr (attr_list, pango_attr_rise_new (text->rise)); - - /* guessing that the x factor is OK here. RNGC */ - zoom = text->item.canvas->pixels_per_unit_x; - if (fabs (zoom - 1.) > 1e-4) { - PangoAttribute *attr = pango_attr_scale_new (zoom); - attr->start_index = 0; - attr->end_index = -1; - pango_attr_list_insert_before (attr_list, attr); - } - - pango_layout_set_attributes (text->layout, attr_list); - pango_attr_list_unref (attr_list); -} - -static void -foo_canvas_text_set_font_desc (FooCanvasText *text, - PangoFontDescription *font_desc) -{ - if (text->font_desc) - pango_font_description_free (text->font_desc); - - if (font_desc) - text->font_desc = pango_font_description_copy (font_desc); - else - text->font_desc = NULL; - - foo_canvas_text_apply_font_desc (text); -} - -/* Setting the text from a Pango markup string */ -static void -foo_canvas_text_set_markup (FooCanvasText *textitem, - const gchar *markup) -{ - PangoAttrList *attr_list = NULL; - gchar *text = NULL; - GError *error = NULL; - - if (textitem->text) - g_free (textitem->text); - if (textitem->attr_list) - pango_attr_list_unref (textitem->attr_list); - - if (markup && !pango_parse_markup (markup, -1, - 0, - &attr_list, &text, NULL, - &error)) - { - g_warning ("Failed to set cell text from markup due to error parsing markup: %s", - error->message); - g_error_free (error); - return; - } - - textitem->text = text; - textitem->attr_list = attr_list; - - pango_layout_set_text (textitem->layout, text, -1); - - foo_canvas_text_apply_attributes (textitem); -} - -/* Update handler for the text item */ -static void -foo_canvas_text_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags) -{ - FooCanvasText *text; - double x1, y1, x2, y2; - - text = FOO_CANVAS_TEXT (item); - - if (parent_class->update) - (* parent_class->update) (item, i2w_dx, i2w_dy, flags); - - set_text_gc_foreground (text); - set_stipple (text, text->stipple, TRUE); - get_bounds (text, &x1, &y1, &x2, &y2); - - foo_canvas_update_bbox (item, - floor (x1), floor (y1), - ceil (x2), ceil (y2)); -} - -/* Realize handler for the text item */ -static void -foo_canvas_text_realize (FooCanvasItem *item) -{ - FooCanvasText *text; - - text = FOO_CANVAS_TEXT (item); - - if (parent_class->realize) - (* parent_class->realize) (item); - - text->gc = gdk_gc_new (item->canvas->layout.bin_window); -} - -/* Unrealize handler for the text item */ -static void -foo_canvas_text_unrealize (FooCanvasItem *item) -{ - FooCanvasText *text; - - text = FOO_CANVAS_TEXT (item); - - g_object_unref (text->gc); - text->gc = NULL; - - if (parent_class->unrealize) - (* parent_class->unrealize) (item); -} - -/* Draw handler for the text item */ -static void -foo_canvas_text_draw (FooCanvasItem *item, GdkDrawable *drawable, - GdkEventExpose *expose) -{ - FooCanvasText *text; - GdkRectangle rect; - - text = FOO_CANVAS_TEXT (item); - - if (!text->text) - return; - - if (text->clip) { - rect.x = text->clip_cx; - rect.y = text->clip_cy; - rect.width = text->clip_cwidth; - rect.height = text->clip_cheight; - - gdk_gc_set_clip_rectangle (text->gc, &rect); - } - - if (text->stipple) - foo_canvas_set_stipple_origin (item->canvas, text->gc); - - - gdk_draw_layout (drawable, text->gc, text->cx, text->cy, text->layout); - - if (text->clip) - gdk_gc_set_clip_rectangle (text->gc, NULL); -} - -/* Point handler for the text item */ -static double -foo_canvas_text_point (FooCanvasItem *item, double x, double y, - int cx, int cy, FooCanvasItem **actual_item) -{ - FooCanvasText *text; - PangoLayoutIter *iter; - int x1, y1, x2, y2; - int dx, dy; - double dist, best; - - text = FOO_CANVAS_TEXT (item); - - *actual_item = item; - - /* The idea is to build bounding rectangles for each of the lines of - * text (clipped by the clipping rectangle, if it is activated) and see - * whether the point is inside any of these. If it is, we are done. - * Otherwise, calculate the distance to the nearest rectangle. - */ - - best = 1.0e36; - - iter = pango_layout_get_iter (text->layout); - do { - PangoRectangle log_rect; - - pango_layout_iter_get_line_extents (iter, NULL, &log_rect); - - if (text->clip) { - x1 = PANGO_PIXELS (log_rect.x); - y1 = PANGO_PIXELS (log_rect.y); - x2 = PANGO_PIXELS (log_rect.x+log_rect.width); - y2 = PANGO_PIXELS (log_rect.y+log_rect.height); - - - if (x1 < text->clip_cx) - x1 = text->clip_cx; - - if (y1 < text->clip_cy) - y1 = text->clip_cy; - - if (x2 > (text->clip_cx + text->clip_width)) - x2 = text->clip_cx + text->clip_width; - - if (y2 > (text->clip_cy + text->clip_height)) - y2 = text->clip_cy + text->clip_height; - - if ((x1 >= x2) || (y1 >= y2)) - continue; - } else { - x1 = text->x; - y1 = text->y; - x2 = log_rect.width; - y2 = log_rect.height; - } - - /* Calculate distance from point to rectangle */ - - if (cx < x1) - dx = x1 - cx; - else if (cx >= x2) - dx = cx - x2 + 1; - else - dx = 0; - - if (cy < y1) - dy = y1 - cy; - else if (cy >= y2) - dy = cy - y2 + 1; - else - dy = 0; - - if ((dx == 0) && (dy == 0)) { - pango_layout_iter_free(iter); - return 0.0; - } - - dist = sqrt (dx * dx + dy * dy); - if (dist < best) - best = dist; - - } while (pango_layout_iter_next_line(iter)); - - pango_layout_iter_free(iter); - - /* guessing that the x factor is OK here. RNGC */ - return best / item->canvas->pixels_per_unit_x; -} - -static void -foo_canvas_text_translate (FooCanvasItem *item, double dx, double dy) -{ - FooCanvasText *text; - - text = FOO_CANVAS_TEXT (item); - - text->x += dx; - text->y += dy; -} - -/* Bounds handler for the text item */ -static void -foo_canvas_text_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2) -{ - FooCanvasText *text; - double width, height; - - text = FOO_CANVAS_TEXT (item); - - *x1 = text->x; - *y1 = text->y; - - if (text->clip) { - width = text->clip_width; - height = text->clip_height; - } else { - width = text->max_width / item->canvas->pixels_per_unit_x; - height = text->height / item->canvas->pixels_per_unit_y; - } - - switch (text->anchor) { - case GTK_ANCHOR_NW: - case GTK_ANCHOR_W: - case GTK_ANCHOR_SW: - break; - - case GTK_ANCHOR_N: - case GTK_ANCHOR_CENTER: - case GTK_ANCHOR_S: - *x1 -= width / 2.0; - break; - - case GTK_ANCHOR_NE: - case GTK_ANCHOR_E: - case GTK_ANCHOR_SE: - *x1 -= width; - break; - - default: - break; - } - - switch (text->anchor) { - case GTK_ANCHOR_NW: - case GTK_ANCHOR_N: - case GTK_ANCHOR_NE: - break; - - case GTK_ANCHOR_W: - case GTK_ANCHOR_CENTER: - case GTK_ANCHOR_E: - *y1 -= height / 2.0; - break; - - case GTK_ANCHOR_SW: - case GTK_ANCHOR_S: - case GTK_ANCHOR_SE: - *y1 -= height; - break; - - default: - break; - } - - *x2 = *x1 + width; - *y2 = *y1 + height; -} diff --git a/foocanvas/foo-canvas-widget.c b/foocanvas/foo-canvas-widget.c deleted file mode 100755 index 55b4a62ea..000000000 --- a/foocanvas/foo-canvas-widget.c +++ /dev/null @@ -1,593 +0,0 @@ -/* Last edited: May 11 11:42 2004 (rnc) */ -/* - * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation - * All rights reserved. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with the Gnome Library; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -/* - @NOTATION@ - */ -/* Widget item type for FooCanvas widget - * - * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget. Tk is - * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties. - * - * - * Author: Federico Mena <federico@nuclecu.unam.mx> - */ - -#include <config.h> -#include <math.h> -#include <gtk/gtksignal.h> -#include "foo-canvas-widget.h" - -enum { - PROP_0, - PROP_WIDGET, - PROP_X, - PROP_Y, - PROP_WIDTH, - PROP_HEIGHT, - PROP_ANCHOR, - PROP_SIZE_PIXELS -}; - - -static void foo_canvas_widget_class_init (FooCanvasWidgetClass *class); -static void foo_canvas_widget_init (FooCanvasWidget *witem); -static void foo_canvas_widget_destroy (GtkObject *object); -static void foo_canvas_widget_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec); -static void foo_canvas_widget_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec); - -static void foo_canvas_widget_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags); -static double foo_canvas_widget_point (FooCanvasItem *item, double x, double y, - int cx, int cy, FooCanvasItem **actual_item); -static void foo_canvas_widget_translate (FooCanvasItem *item, double dx, double dy); -static void foo_canvas_widget_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2); - -static void foo_canvas_widget_draw (FooCanvasItem *item, - GdkDrawable *drawable, - GdkEventExpose *event); - -static FooCanvasItemClass *parent_class; - - -GtkType -foo_canvas_widget_get_type (void) -{ - static GtkType witem_type = 0; - - if (!witem_type) { - /* FIXME: Convert to gobject style. */ - static const GtkTypeInfo witem_info = { - (char *)"FooCanvasWidget", - sizeof (FooCanvasWidget), - sizeof (FooCanvasWidgetClass), - (GtkClassInitFunc) foo_canvas_widget_class_init, - (GtkObjectInitFunc) foo_canvas_widget_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - witem_type = gtk_type_unique (foo_canvas_item_get_type (), &witem_info); - } - - return witem_type; -} - -static void -foo_canvas_widget_class_init (FooCanvasWidgetClass *class) -{ - GObjectClass *gobject_class; - GtkObjectClass *object_class; - FooCanvasItemClass *item_class; - - gobject_class = (GObjectClass *) class; - object_class = (GtkObjectClass *) class; - item_class = (FooCanvasItemClass *) class; - - parent_class = gtk_type_class (foo_canvas_item_get_type ()); - - gobject_class->set_property = foo_canvas_widget_set_property; - gobject_class->get_property = foo_canvas_widget_get_property; - - g_object_class_install_property - (gobject_class, - PROP_WIDGET, - g_param_spec_object ("widget", NULL, NULL, - GTK_TYPE_WIDGET, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_X, - g_param_spec_double ("x", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_Y, - g_param_spec_double ("y", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_WIDTH, - g_param_spec_double ("width", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_HEIGHT, - g_param_spec_double ("height", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_ANCHOR, - g_param_spec_enum ("anchor", NULL, NULL, - GTK_TYPE_ANCHOR_TYPE, - GTK_ANCHOR_NW, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, - PROP_SIZE_PIXELS, - g_param_spec_boolean ("size_pixels", NULL, NULL, - FALSE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - - object_class->destroy = foo_canvas_widget_destroy; - - item_class->update = foo_canvas_widget_update; - item_class->point = foo_canvas_widget_point; - item_class->translate = foo_canvas_widget_translate; - item_class->bounds = foo_canvas_widget_bounds; - item_class->draw = foo_canvas_widget_draw; -} - -static void -foo_canvas_widget_init (FooCanvasWidget *witem) -{ - witem->x = 0.0; - witem->y = 0.0; - witem->width = 0.0; - witem->height = 0.0; - witem->anchor = GTK_ANCHOR_NW; - witem->size_pixels = FALSE; -} - -static void -foo_canvas_widget_destroy (GtkObject *object) -{ - FooCanvasWidget *witem; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_WIDGET (object)); - - witem = FOO_CANVAS_WIDGET (object); - - if (witem->widget && !witem->in_destroy) { - gtk_signal_disconnect (GTK_OBJECT (witem->widget), witem->destroy_id); - gtk_widget_destroy (witem->widget); - witem->widget = NULL; - } - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -static void -recalc_bounds (FooCanvasWidget *witem) -{ - FooCanvasItem *item; - double wx, wy; - - item = FOO_CANVAS_ITEM (witem); - - /* Get world coordinates */ - - wx = witem->x; - wy = witem->y; - foo_canvas_item_i2w (item, &wx, &wy); - - /* Get canvas pixel coordinates */ - - foo_canvas_w2c (item->canvas, wx, wy, &witem->cx, &witem->cy); - - /* Anchor widget item */ - - switch (witem->anchor) { - case GTK_ANCHOR_NW: - case GTK_ANCHOR_W: - case GTK_ANCHOR_SW: - break; - - case GTK_ANCHOR_N: - case GTK_ANCHOR_CENTER: - case GTK_ANCHOR_S: - witem->cx -= witem->cwidth / 2; - break; - - case GTK_ANCHOR_NE: - case GTK_ANCHOR_E: - case GTK_ANCHOR_SE: - witem->cx -= witem->cwidth; - break; - - default: - break; - } - - switch (witem->anchor) { - case GTK_ANCHOR_NW: - case GTK_ANCHOR_N: - case GTK_ANCHOR_NE: - break; - - case GTK_ANCHOR_W: - case GTK_ANCHOR_CENTER: - case GTK_ANCHOR_E: - witem->cy -= witem->cheight / 2; - break; - - case GTK_ANCHOR_SW: - case GTK_ANCHOR_S: - case GTK_ANCHOR_SE: - witem->cy -= witem->cheight; - break; - - default: - break; - } - - /* Bounds */ - - item->x1 = witem->cx; - item->y1 = witem->cy; - item->x2 = witem->cx + witem->cwidth; - item->y2 = witem->cy + witem->cheight; - - if (witem->widget) - gtk_layout_move (GTK_LAYOUT (item->canvas), witem->widget, - witem->cx, - witem->cy); -} - -static void -do_destroy (GtkObject *object, gpointer data) -{ - FooCanvasWidget *witem; - - witem = data; - - witem->in_destroy = TRUE; - - gtk_object_destroy (data); -} - -static void -foo_canvas_widget_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) -{ - FooCanvasItem *item; - FooCanvasWidget *witem; - GObject *obj; - int update; - int calc_bounds; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_WIDGET (object)); - - item = FOO_CANVAS_ITEM (object); - witem = FOO_CANVAS_WIDGET (object); - - update = FALSE; - calc_bounds = FALSE; - - switch (param_id) { - case PROP_WIDGET: - if (witem->widget) { - gtk_signal_disconnect (GTK_OBJECT (witem->widget), witem->destroy_id); - gtk_container_remove (GTK_CONTAINER (item->canvas), witem->widget); - } - - obj = g_value_get_object (value); - if (obj) { - witem->widget = GTK_WIDGET (obj); - witem->destroy_id = gtk_signal_connect (GTK_OBJECT (obj), - "destroy", - (GtkSignalFunc) do_destroy, - witem); - gtk_layout_put (GTK_LAYOUT (item->canvas), witem->widget, - witem->cx + item->canvas->zoom_xofs, - witem->cy + item->canvas->zoom_yofs); - } - - update = TRUE; - break; - - case PROP_X: - if (witem->x != g_value_get_double (value)) - { - witem->x = g_value_get_double (value); - calc_bounds = TRUE; - } - break; - - case PROP_Y: - if (witem->y != g_value_get_double (value)) - { - witem->y = g_value_get_double (value); - calc_bounds = TRUE; - } - break; - - case PROP_WIDTH: - if (witem->width != fabs (g_value_get_double (value))) - { - witem->width = fabs (g_value_get_double (value)); - update = TRUE; - } - break; - - case PROP_HEIGHT: - if (witem->height != fabs (g_value_get_double (value))) - { - witem->height = fabs (g_value_get_double (value)); - update = TRUE; - } - break; - - case PROP_ANCHOR: - if (witem->anchor != (GtkAnchorType)g_value_get_enum (value)) - { - witem->anchor = g_value_get_enum (value); - update = TRUE; - } - break; - - case PROP_SIZE_PIXELS: - if (witem->size_pixels != g_value_get_boolean (value)) - { - witem->size_pixels = g_value_get_boolean (value); - update = TRUE; - } - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } - - if (update) - (* FOO_CANVAS_ITEM_GET_CLASS (item)->update) (item, 0, 0, 0); - - if (calc_bounds) - recalc_bounds (witem); -} - -static void -foo_canvas_widget_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec) -{ - FooCanvasWidget *witem; - - g_return_if_fail (object != NULL); - g_return_if_fail (FOO_IS_CANVAS_WIDGET (object)); - - witem = FOO_CANVAS_WIDGET (object); - - switch (param_id) { - case PROP_WIDGET: - g_value_set_object (value, (GObject *) witem->widget); - break; - - case PROP_X: - g_value_set_double (value, witem->x); - break; - - case PROP_Y: - g_value_set_double (value, witem->y); - break; - - case PROP_WIDTH: - g_value_set_double (value, witem->width); - break; - - case PROP_HEIGHT: - g_value_set_double (value, witem->height); - break; - - case PROP_ANCHOR: - g_value_set_enum (value, witem->anchor); - break; - - case PROP_SIZE_PIXELS: - g_value_set_boolean (value, witem->size_pixels); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -static void -foo_canvas_widget_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags) -{ - FooCanvasWidget *witem; - - witem = FOO_CANVAS_WIDGET (item); - - if (parent_class->update) - (* parent_class->update) (item, i2w_dx, i2w_dy, flags); - - if (witem->widget) { - if (witem->size_pixels) { - witem->cwidth = (int) (witem->width + 0.5); - witem->cheight = (int) (witem->height + 0.5); - } else { - witem->cwidth = (int) (witem->width * item->canvas->pixels_per_unit_x + 0.5); - witem->cheight = (int) (witem->height * item->canvas->pixels_per_unit_y + 0.5); - } - - gtk_widget_set_usize (witem->widget, witem->cwidth, witem->cheight); - } else { - witem->cwidth = 0.0; - witem->cheight = 0.0; - } - - recalc_bounds (witem); -} - -static void -foo_canvas_widget_draw (FooCanvasItem *item, - GdkDrawable *drawable, - GdkEventExpose *event) -{ -#if 0 - FooCanvasWidget *witem; - - witem = FOO_CANVAS_WIDGET (item); - - if (witem->widget) - gtk_widget_queue_draw (witem->widget); -#endif -} - -static double -foo_canvas_widget_point (FooCanvasItem *item, double x, double y, - int cx, int cy, FooCanvasItem **actual_item) -{ - FooCanvasWidget *witem; - double x1, y1, x2, y2; - double dx, dy; - - witem = FOO_CANVAS_WIDGET (item); - - *actual_item = item; - - foo_canvas_c2w (item->canvas, witem->cx, witem->cy, &x1, &y1); - - x2 = x1 + (witem->cwidth - 1) / item->canvas->pixels_per_unit_x; - y2 = y1 + (witem->cheight - 1) / item->canvas->pixels_per_unit_y; - - /* Is point inside widget bounds? */ - - if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) - return 0.0; - - /* Point is outside widget bounds */ - - if (x < x1) - dx = x1 - x; - else if (x > x2) - dx = x - x2; - else - dx = 0.0; - - if (y < y1) - dy = y1 - y; - else if (y > y2) - dy = y - y2; - else - dy = 0.0; - - return sqrt (dx * dx + dy * dy); -} - -static void -foo_canvas_widget_translate (FooCanvasItem *item, double dx, double dy) -{ - FooCanvasWidget *witem; - - witem = FOO_CANVAS_WIDGET (item); - - witem->x += dx; - witem->y += dy; -} - - -static void -foo_canvas_widget_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2) -{ - FooCanvasWidget *witem; - - witem = FOO_CANVAS_WIDGET (item); - - *x1 = witem->x; - *y1 = witem->y; - - switch (witem->anchor) { - case GTK_ANCHOR_NW: - case GTK_ANCHOR_W: - case GTK_ANCHOR_SW: - break; - - case GTK_ANCHOR_N: - case GTK_ANCHOR_CENTER: - case GTK_ANCHOR_S: - *x1 -= witem->width / 2.0; - break; - - case GTK_ANCHOR_NE: - case GTK_ANCHOR_E: - case GTK_ANCHOR_SE: - *x1 -= witem->width; - break; - - default: - break; - } - - switch (witem->anchor) { - case GTK_ANCHOR_NW: - case GTK_ANCHOR_N: - case GTK_ANCHOR_NE: - break; - - case GTK_ANCHOR_W: - case GTK_ANCHOR_CENTER: - case GTK_ANCHOR_E: - *y1 -= witem->height / 2.0; - break; - - case GTK_ANCHOR_SW: - case GTK_ANCHOR_S: - case GTK_ANCHOR_SE: - *y1 -= witem->height; - break; - - default: - break; - } - - *x2 = *x1 + witem->width; - *y2 = *y1 + witem->height; -} diff --git a/foocanvas/foo-canvas.c b/foocanvas/foo-canvas.c deleted file mode 100755 index 9377ae405..000000000 --- a/foocanvas/foo-canvas.c +++ /dev/null @@ -1,4027 +0,0 @@ -/* Last edited: Jun 15 08:19 2005 (edgrif) */ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation - * All rights reserved. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with the Gnome Library; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -/* - @NOTATION@ - */ -/* - * FooCanvas widget - Tk-like canvas widget for Gnome - * - * FooCanvas is basically a port of the Tk toolkit's most excellent canvas widget. Tk is - * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties. - * - * - * Authors: Federico Mena <federico@nuclecu.unam.mx> - * Raph Levien <raph@gimp.org> - */ - -/* - * TO-DO list for the canvas: - * - * - Allow to specify whether FooCanvasImage sizes are in units or pixels (scale or don't scale). - * - * - Implement a flag for foo_canvas_item_reparent() that tells the function to keep the item - * visually in the same place, that is, to keep it in the same place with respect to the canvas - * origin. - * - * - GC put functions for items. - * - * - Widget item (finish it). - * - * - GList *foo_canvas_gimme_all_items_contained_in_this_area (FooCanvas *canvas, Rectangle area); - * - * - Retrofit all the primitive items with microtile support. - * - * - Curve support for line item. - * - * - Arc item (Havoc has it; to be integrated in FooCanvasEllipse). - * - * - Sane font handling API. - * - * - Get_arg methods for items: - * - How to fetch the outline width and know whether it is in pixels or units? - */ - -#include <config.h> - -#include <math.h> -#include <string.h> -#include <stdio.h> -#include <gdk/gdkprivate.h> -#include <gtk/gtkmain.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkaccessible.h> -#include <gtk/gtkwindow.h> -#include "foo-canvas.h" -#include "foo-canvas-i18n.h" - -#include "foo-canvas-marshal.h" - -static void foo_canvas_request_update (FooCanvas *canvas); -static void group_add (FooCanvasGroup *group, - FooCanvasItem *item); -static void group_remove (FooCanvasGroup *group, - FooCanvasItem *item); -static void redraw_and_repick_if_mapped (FooCanvasItem *item); - -/*** FooCanvasItem ***/ - -/* Some convenience stuff */ -#define GCI_UPDATE_MASK (FOO_CANVAS_UPDATE_REQUESTED | FOO_CANVAS_UPDATE_DEEP) -#define GCI_EPSILON 1e-18 - -enum { - ITEM_PROP_0, - ITEM_PROP_PARENT, - ITEM_PROP_VISIBLE -}; - -enum { - ITEM_EVENT, - ITEM_LAST_SIGNAL -}; - -static void foo_canvas_item_class_init (FooCanvasItemClass *class); -static void foo_canvas_item_init (FooCanvasItem *item); -static int emit_event (FooCanvas *canvas, GdkEvent *event); - -static guint item_signals[ITEM_LAST_SIGNAL]; - -static GtkObjectClass *item_parent_class; - -static gpointer accessible_item_parent_class; -static gpointer accessible_parent_class; - - -/** - * foo_canvas_item_get_type: - * - * Registers the &FooCanvasItem class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &FooCanvasItem class. - **/ -GType -foo_canvas_item_get_type (void) -{ - static GType canvas_item_type = 0; - - if (!canvas_item_type) { - static const GTypeInfo canvas_item_info = { - sizeof (FooCanvasItemClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) foo_canvas_item_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (FooCanvasItem), - 0, /* n_preallocs */ - (GInstanceInitFunc) foo_canvas_item_init - }; - - canvas_item_type = g_type_register_static (gtk_object_get_type (), - "FooCanvasItem", - &canvas_item_info, - 0); - } - - return canvas_item_type; -} - -/* Object initialization function for FooCanvasItem */ -static void -foo_canvas_item_init (FooCanvasItem *item) -{ - item->object.flags |= FOO_CANVAS_ITEM_VISIBLE; -} - -/** - * foo_canvas_item_new: - * @parent: The parent group for the new item. - * @type: The object type of the item. - * @first_arg_name: A list of object argument name/value pairs, NULL-terminated, - * used to configure the item. For example, "fill_color", "black", - * "width_units", 5.0, NULL. - * @Varargs: - * - * Creates a new canvas item with @parent as its parent group. The item is - * created at the top of its parent's stack, and starts up as visible. The item - * is of the specified @type, for example, it can be - * foo_canvas_rect_get_type(). The list of object arguments/value pairs is - * used to configure the item. - * - * Return value: The newly-created item. - **/ -FooCanvasItem * -foo_canvas_item_new (FooCanvasGroup *parent, GType type, const gchar *first_arg_name, ...) -{ - FooCanvasItem *item; - va_list args; - - g_return_val_if_fail (FOO_IS_CANVAS_GROUP (parent), NULL); - g_return_val_if_fail (g_type_is_a (type, foo_canvas_item_get_type ()), NULL); - - item = FOO_CANVAS_ITEM (g_object_new (type, NULL)); - - va_start (args, first_arg_name); - foo_canvas_item_construct (item, parent, first_arg_name, args); - va_end (args); - - return item; -} - - -/* Performs post-creation operations on a canvas item (adding it to its parent - * group, etc.) - */ -static void -item_post_create_setup (FooCanvasItem *item) -{ - GtkObject *obj; - - obj = GTK_OBJECT (item); - - group_add (FOO_CANVAS_GROUP (item->parent), item); - - redraw_and_repick_if_mapped (item); -} - -/* Set_property handler for canvas items */ -static void -foo_canvas_item_set_property (GObject *gobject, guint param_id, - const GValue *value, GParamSpec *pspec) -{ - FooCanvasItem *item; - - g_return_if_fail (FOO_IS_CANVAS_ITEM (gobject)); - - item = FOO_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)) { - item->parent = FOO_CANVAS_ITEM (g_value_get_object (value)); - item->canvas = item->parent->canvas; - item_post_create_setup (item); - } - break; - case ITEM_PROP_VISIBLE: - if (g_value_get_boolean (value)) { - foo_canvas_item_show (item); - } else { - foo_canvas_item_hide (item); - } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec); - break; - } -} - -/* Get_property handler for canvas items */ -static void -foo_canvas_item_get_property (GObject *gobject, guint param_id, - GValue *value, GParamSpec *pspec) -{ - FooCanvasItem *item; - - g_return_if_fail (FOO_IS_CANVAS_ITEM (gobject)); - - item = FOO_CANVAS_ITEM (gobject); - - switch (param_id) { - case ITEM_PROP_VISIBLE: - g_value_set_boolean (value, item->object.flags & FOO_CANVAS_ITEM_VISIBLE); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec); - break; - } -} - -/** - * foo_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 -foo_canvas_item_construct (FooCanvasItem *item, FooCanvasGroup *parent, - const gchar *first_arg_name, va_list args) -{ - g_return_if_fail (FOO_IS_CANVAS_GROUP (parent)); - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - - item->parent = FOO_CANVAS_ITEM (parent); - item->canvas = item->parent->canvas; - - g_object_set_valist (G_OBJECT (item), first_arg_name, args); - - item_post_create_setup (item); -} - - -static void -redraw_and_repick_if_mapped (FooCanvasItem *item) -{ - if (item->object.flags & FOO_CANVAS_ITEM_MAPPED) { - foo_canvas_item_request_redraw (item); - item->canvas->need_repick = TRUE; - } -} - - -/* Standard object dispose function for canvas items */ -static void -foo_canvas_item_dispose (GObject *object) -{ - FooCanvasItem *item; - - g_return_if_fail (FOO_IS_CANVAS_ITEM (object)); - - item = FOO_CANVAS_ITEM (object); - - foo_canvas_item_request_redraw (item); - - /* Make the canvas forget about us */ - - if (item == item->canvas->current_item) { - item->canvas->current_item = NULL; - item->canvas->need_repick = TRUE; - } - - if (item == item->canvas->new_current_item) { - item->canvas->new_current_item = NULL; - item->canvas->need_repick = TRUE; - } - - if (item == item->canvas->grabbed_item) { - GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (item->canvas)); - item->canvas->grabbed_item = NULL; - gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME); - } - - if (item == item->canvas->focused_item) - item->canvas->focused_item = NULL; - - /* Normal destroy stuff */ - - if (item->object.flags & FOO_CANVAS_ITEM_MAPPED) - (* FOO_CANVAS_ITEM_GET_CLASS (item)->unmap) (item); - - if (item->object.flags & FOO_CANVAS_ITEM_REALIZED) - (* FOO_CANVAS_ITEM_GET_CLASS (item)->unrealize) (item); - - if (item->parent) - group_remove (FOO_CANVAS_GROUP (item->parent), item); - - G_OBJECT_CLASS (item_parent_class)->dispose (object); -} - -/* Realize handler for canvas items */ -static void -foo_canvas_item_realize (FooCanvasItem *item) -{ - if (item->parent && !(item->parent->object.flags & FOO_CANVAS_ITEM_REALIZED)) - (* FOO_CANVAS_ITEM_GET_CLASS (item->parent)->realize) (item->parent); - - if (item->parent == NULL && !GTK_WIDGET_REALIZED (GTK_WIDGET (item->canvas))) - gtk_widget_realize (GTK_WIDGET (item->canvas)); - - GTK_OBJECT_SET_FLAGS (item, FOO_CANVAS_ITEM_REALIZED); - - foo_canvas_item_request_update (item); -} - -/* Unrealize handler for canvas items */ -static void -foo_canvas_item_unrealize (FooCanvasItem *item) -{ - if (item->object.flags & FOO_CANVAS_ITEM_MAPPED) - (* FOO_CANVAS_ITEM_GET_CLASS (item)->unmap) (item); - - GTK_OBJECT_UNSET_FLAGS (item, FOO_CANVAS_ITEM_REALIZED); -} - -/* Map handler for canvas items */ -static void -foo_canvas_item_map (FooCanvasItem *item) -{ - GTK_OBJECT_SET_FLAGS (item, FOO_CANVAS_ITEM_MAPPED); -} - -/* Unmap handler for canvas items */ -static void -foo_canvas_item_unmap (FooCanvasItem *item) -{ - GTK_OBJECT_UNSET_FLAGS (item, FOO_CANVAS_ITEM_MAPPED); -} - -/* Update handler for canvas items */ -static void -foo_canvas_item_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags) -{ - GTK_OBJECT_UNSET_FLAGS (item, FOO_CANVAS_ITEM_NEED_UPDATE); - GTK_OBJECT_UNSET_FLAGS (item, FOO_CANVAS_ITEM_NEED_DEEP_UPDATE); -} - -/* - * This routine invokes the update method of the item - * Please notice, that we take parent to canvas pixel matrix as argument - * unlike virtual method ::update, whose argument is item 2 canvas pixel - * matrix - * - * I will try to force somewhat meaningful naming for affines (Lauris) - * General naming rule is FROM2TO, where FROM and TO are abbreviations - * So p2cpx is Parent2CanvasPixel and i2cpx is Item2CanvasPixel - * I hope that this helps to keep track of what really happens - * - */ - -static void -foo_canvas_item_invoke_update (FooCanvasItem *item, - double i2w_dx, - double i2w_dy, - int flags) -{ - int child_flags; - - child_flags = flags; - - /* apply object flags to child flags */ - child_flags &= ~FOO_CANVAS_UPDATE_REQUESTED; - - if (item->object.flags & FOO_CANVAS_ITEM_NEED_UPDATE) - child_flags |= FOO_CANVAS_UPDATE_REQUESTED; - - if (item->object.flags & FOO_CANVAS_ITEM_NEED_DEEP_UPDATE) - child_flags |= FOO_CANVAS_UPDATE_DEEP; - - if (child_flags & GCI_UPDATE_MASK) { - if (FOO_CANVAS_ITEM_GET_CLASS (item)->update) - FOO_CANVAS_ITEM_GET_CLASS (item)->update (item, i2w_dx, i2w_dy, child_flags); - } - - /* If this fail you probably forgot to chain up to - * FooCanvasItem::update from a derived class */ - g_return_if_fail (!(item->object.flags & FOO_CANVAS_ITEM_NEED_UPDATE)); -} - -/* - * This routine invokes the point method of the item. - * The arguments x, y should be in the parent item local coordinates. - */ - -static double -foo_canvas_item_invoke_point (FooCanvasItem *item, double x, double y, int cx, int cy, FooCanvasItem **actual_item) -{ - /* Calculate x & y in item local coordinates */ - - if (FOO_CANVAS_ITEM_GET_CLASS (item)->point) - return FOO_CANVAS_ITEM_GET_CLASS (item)->point (item, x, y, cx, cy, actual_item); - - return 1e18; -} - -/** - * foo_canvas_item_set: - * @item: A canvas item. - * @first_arg_name: The list of object argument name/value pairs used to configure the item. - * @Varargs: - * - * Configures a canvas item. The arguments in the item are set to the specified - * values, and the item is repainted as appropriate. - **/ -void -foo_canvas_item_set (FooCanvasItem *item, const gchar *first_arg_name, ...) -{ - va_list args; - - va_start (args, first_arg_name); - foo_canvas_item_set_valist (item, first_arg_name, args); - va_end (args); -} - - -/** - * foo_canvas_item_set_valist: - * @item: A canvas item. - * @first_arg_name: The name of the first argument used to configure the item. - * @args: The list of object argument name/value pairs used to configure the item. - * - * Configures a canvas item. The arguments in the item are set to the specified - * values, and the item is repainted as appropriate. - **/ -void -foo_canvas_item_set_valist (FooCanvasItem *item, const gchar *first_arg_name, va_list args) -{ - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - - g_object_set_valist (G_OBJECT (item), first_arg_name, args); - -#if 0 - /* I commented this out, because item implementations have to schedule update/redraw */ - foo_canvas_item_request_redraw (item); -#endif - - item->canvas->need_repick = TRUE; -} - - -/** - * foo_canvas_item_move: - * @item: A canvas item. - * @dx: Horizontal offset. - * @dy: Vertical offset. - * - * Moves a canvas item by creating an affine transformation matrix for - * translation by using the specified values. This happens in item - * local coordinate system, so if you have nontrivial transform, it - * most probably does not do, what you want. - **/ -void -foo_canvas_item_move (FooCanvasItem *item, double dx, double dy) -{ - g_return_if_fail (item != NULL); - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - - if (!FOO_CANVAS_ITEM_GET_CLASS (item)->translate) { - g_warning ("Item type %s does not implement translate method.\n", - g_type_name (GTK_OBJECT_TYPE (item))); - return; - } - - (* FOO_CANVAS_ITEM_GET_CLASS (item)->translate) (item, dx, dy); - - if (item->object.flags & FOO_CANVAS_ITEM_MAPPED) - item->canvas->need_repick = TRUE; - - if (!(item->object.flags & FOO_CANVAS_ITEM_NEED_DEEP_UPDATE)) { - item->object.flags |= FOO_CANVAS_ITEM_NEED_DEEP_UPDATE; - if (item->parent != NULL) - foo_canvas_item_request_update (item->parent); - else - foo_canvas_request_update (item->canvas); - } - -} - -/* Convenience function to reorder items in a group's child list. This puts the - * specified link after the "before" link. Returns TRUE if the list was changed. - */ -static gboolean -put_item_after (GList *link, GList *before) -{ - FooCanvasGroup *parent; - - if (link == before) - return FALSE; - - parent = FOO_CANVAS_GROUP (FOO_CANVAS_ITEM (link->data)->parent); - - if (before == NULL) { - if (link == parent->item_list) - return FALSE; - - link->prev->next = link->next; - - if (link->next) - link->next->prev = link->prev; - else - parent->item_list_end = link->prev; - - link->prev = before; - link->next = parent->item_list; - link->next->prev = link; - parent->item_list = link; - } else { - if ((link == parent->item_list_end) && (before == parent->item_list_end->prev)) - return FALSE; - - if (link->next) - link->next->prev = link->prev; - - if (link->prev) - link->prev->next = link->next; - else { - parent->item_list = link->next; - parent->item_list->prev = NULL; - } - - link->prev = before; - link->next = before->next; - - link->prev->next = link; - - if (link->next) - link->next->prev = link; - else - parent->item_list_end = link; - } - return TRUE; -} - - -/** - * foo_canvas_item_raise: - * @item: A canvas item. - * @positions: Number of steps to raise the item. - * - * Raises the item in its parent's stack by the specified number of positions. - * If the number of positions is greater than the distance to the top of the - * stack, then the item is put at the top. - **/ -void -foo_canvas_item_raise (FooCanvasItem *item, int positions) -{ - GList *link, *before; - FooCanvasGroup *parent; - - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - g_return_if_fail (positions >= 0); - - if (!item->parent || positions == 0) - return; - - parent = FOO_CANVAS_GROUP (item->parent); - link = g_list_find (parent->item_list, item); - g_assert (link != NULL); - - for (before = link; positions && before; positions--) - before = before->next; - - if (!before) - before = parent->item_list_end; - - if (put_item_after (link, before)) { - redraw_and_repick_if_mapped (item); - } -} - - -/** - * foo_canvas_item_lower: - * @item: A canvas item. - * @positions: Number of steps to lower the item. - * - * Lowers the item in its parent's stack by the specified number of positions. - * If the number of positions is greater than the distance to the bottom of the - * stack, then the item is put at the bottom. - **/ -void -foo_canvas_item_lower (FooCanvasItem *item, int positions) -{ - GList *link, *before; - FooCanvasGroup *parent; - - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - g_return_if_fail (positions >= 1); - - if (!item->parent || positions == 0) - return; - - parent = FOO_CANVAS_GROUP (item->parent); - link = g_list_find (parent->item_list, item); - g_assert (link != NULL); - - if (link->prev) - for (before = link->prev; positions && before; positions--) - before = before->prev; - else - before = NULL; - - if (put_item_after (link, before)) { - redraw_and_repick_if_mapped (item); - } -} - - -/** - * foo_canvas_item_raise_to_top: - * @item: A canvas item. - * - * Raises an item to the top of its parent's stack. - **/ -void -foo_canvas_item_raise_to_top (FooCanvasItem *item) -{ - GList *link; - FooCanvasGroup *parent; - - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - - if (!item->parent) - return; - - parent = FOO_CANVAS_GROUP (item->parent); - link = g_list_find (parent->item_list, item); - g_assert (link != NULL); - - if (put_item_after (link, parent->item_list_end)) { - redraw_and_repick_if_mapped (item); - } -} - - -/** - * foo_canvas_item_lower_to_bottom: - * @item: A canvas item. - * - * Lowers an item to the bottom of its parent's stack. - **/ -void -foo_canvas_item_lower_to_bottom (FooCanvasItem *item) -{ - GList *link; - FooCanvasGroup *parent; - - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - - if (!item->parent) - return; - - parent = FOO_CANVAS_GROUP (item->parent); - link = g_list_find (parent->item_list, item); - g_assert (link != NULL); - - if (put_item_after (link, NULL)) { - redraw_and_repick_if_mapped (item); - } -} - -/** - * foo_canvas_item_send_behind: - * @item: A canvas item. - * @behind_item: The canvas item to put item behind, or NULL - * - * Moves item to a in the position in the stacking order so that - * it is placed immediately below behind_item, or at the top if - * behind_item is NULL. - **/ -void -foo_canvas_item_send_behind (FooCanvasItem *item, - FooCanvasItem *behind_item) -{ - GList *item_list; - int item_position, behind_position; - - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - - if (behind_item == NULL) { - foo_canvas_item_raise_to_top (item); - return; - } - - g_return_if_fail (FOO_IS_CANVAS_ITEM (behind_item)); - g_return_if_fail (item->parent == behind_item->parent); - - item_list = FOO_CANVAS_GROUP (item->parent)->item_list; - - item_position = g_list_index (item_list, item); - g_assert (item_position != -1); - behind_position = g_list_index (item_list, behind_item); - g_assert (behind_position != -1); - g_assert (item_position != behind_position); - - if (item_position == behind_position - 1) { - return; - } - - if (item_position < behind_position) { - foo_canvas_item_raise (item, (behind_position - 1) - item_position); - } else { - foo_canvas_item_lower (item, item_position - behind_position); - } -} - -/** - * foo_canvas_item_show: - * @item: A canvas item. - * - * Shows a canvas item. If the item was already shown, then no action is taken. - **/ -void -foo_canvas_item_show (FooCanvasItem *item) -{ - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - - if (!(item->object.flags & FOO_CANVAS_ITEM_VISIBLE)) { - item->object.flags |= FOO_CANVAS_ITEM_VISIBLE; - - if (!(item->object.flags & FOO_CANVAS_ITEM_REALIZED)) - (* FOO_CANVAS_ITEM_GET_CLASS (item)->realize) (item); - - if (item->parent != NULL) { - if (!(item->object.flags & FOO_CANVAS_ITEM_MAPPED) && - item->parent->object.flags & FOO_CANVAS_ITEM_MAPPED) - (* FOO_CANVAS_ITEM_GET_CLASS (item)->map) (item); - } else { - if (!(item->object.flags & FOO_CANVAS_ITEM_MAPPED) && - GTK_WIDGET_MAPPED (GTK_WIDGET (item->canvas))) - (* FOO_CANVAS_ITEM_GET_CLASS (item)->map) (item); - } - - redraw_and_repick_if_mapped (item); - } -} - - -/** - * foo_canvas_item_hide: - * @item: A canvas item. - * - * Hides a canvas item. If the item was already hidden, then no action is - * taken. - **/ -void -foo_canvas_item_hide (FooCanvasItem *item) -{ - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - - if (item->object.flags & FOO_CANVAS_ITEM_VISIBLE) { - item->object.flags &= ~FOO_CANVAS_ITEM_VISIBLE; - - redraw_and_repick_if_mapped (item); - - if (item->object.flags & FOO_CANVAS_ITEM_MAPPED) - (* FOO_CANVAS_ITEM_GET_CLASS (item)->unmap) (item); - - /* No need to unrealize when we just want to hide */ - } -} - - -/** - * foo_canvas_item_grab: - * @item: A canvas item. - * @event_mask: Mask of events that will be sent to this item. - * @cursor: If non-NULL, the cursor that will be used while the grab is active. - * @etime: The timestamp required for grabbing the mouse, or GDK_CURRENT_TIME. - * - * Specifies that all events that match the specified event mask should be sent - * to the specified item, and also grabs the mouse by calling - * gdk_pointer_grab(). The event mask is also used when grabbing the pointer. - * If @cursor is not NULL, then that cursor is used while the grab is active. - * The @etime parameter is the timestamp required for grabbing the mouse. - * - * Return value: If an item was already grabbed, it returns %GDK_GRAB_ALREADY_GRABBED. If - * the specified item was hidden by calling foo_canvas_item_hide(), then it - * returns %GDK_GRAB_NOT_VIEWABLE. Else, it returns the result of calling - * gdk_pointer_grab(). - **/ -int -foo_canvas_item_grab (FooCanvasItem *item, guint event_mask, GdkCursor *cursor, guint32 etime) -{ - int retval; - - g_return_val_if_fail (FOO_IS_CANVAS_ITEM (item), GDK_GRAB_NOT_VIEWABLE); - g_return_val_if_fail (GTK_WIDGET_MAPPED (item->canvas), GDK_GRAB_NOT_VIEWABLE); - - if (item->canvas->grabbed_item) - return GDK_GRAB_ALREADY_GRABBED; - - if (!(item->object.flags & FOO_CANVAS_ITEM_MAPPED)) - return GDK_GRAB_NOT_VIEWABLE; - - retval = gdk_pointer_grab (item->canvas->layout.bin_window, - FALSE, - event_mask, - NULL, - cursor, - etime); - - if (retval != GDK_GRAB_SUCCESS) - return retval; - - item->canvas->grabbed_item = item; - item->canvas->grabbed_event_mask = event_mask; - item->canvas->current_item = item; /* So that events go to the grabbed item */ - - return retval; -} - - -/** - * foo_canvas_item_ungrab: - * @item: A canvas item that holds a grab. - * @etime: The timestamp for ungrabbing the mouse. - * - * Ungrabs the item, which must have been grabbed in the canvas, and ungrabs the - * mouse. - **/ -void -foo_canvas_item_ungrab (FooCanvasItem *item, guint32 etime) -{ - GdkDisplay *display; - - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - - if (item->canvas->grabbed_item != item) - return; - - display = gtk_widget_get_display (GTK_WIDGET (item->canvas)); - item->canvas->grabbed_item = NULL; - gdk_display_pointer_ungrab (display, etime); -} - - -/** - * foo_canvas_item_w2i: - * @item: A canvas item. - * @x: X coordinate to convert (input/output value). - * @y: Y coordinate to convert (input/output value). - * - * Converts a coordinate pair from world coordinates to item-relative - * coordinates. - **/ -void -foo_canvas_item_w2i (FooCanvasItem *item, double *x, double *y) -{ - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - g_return_if_fail (x != NULL); - g_return_if_fail (y != NULL); - - item = item->parent; - while (item) { - if (FOO_IS_CANVAS_GROUP (item)) { - *x -= FOO_CANVAS_GROUP (item)->xpos; - *y -= FOO_CANVAS_GROUP (item)->ypos; - } - - item = item->parent; - } -} - - -/** - * foo_canvas_item_i2w: - * @item: A canvas item. - * @x: X coordinate to convert (input/output value). - * @y: Y coordinate to convert (input/output value). - * - * Converts a coordinate pair from item-relative coordinates to world - * coordinates. - **/ -void -foo_canvas_item_i2w (FooCanvasItem *item, double *x, double *y) -{ - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - g_return_if_fail (x != NULL); - g_return_if_fail (y != NULL); - - item = item->parent; - while (item) { - if (FOO_IS_CANVAS_GROUP (item)) { - *x += FOO_CANVAS_GROUP (item)->xpos; - *y += FOO_CANVAS_GROUP (item)->ypos; - } - - item = item->parent; - } -} - -/* Returns whether the item is an inferior of or is equal to the parent. */ -static int -is_descendant (FooCanvasItem *item, FooCanvasItem *parent) -{ - for (; item; item = item->parent) - if (item == parent) - return TRUE; - - return FALSE; -} - -/** - * foo_canvas_item_reparent: - * @item: A canvas item. - * @new_group: A canvas group. - * - * Changes the parent of the specified item to be the new group. The item keeps - * its group-relative coordinates as for its old parent, so the item may change - * its absolute position within the canvas. - **/ -void -foo_canvas_item_reparent (FooCanvasItem *item, FooCanvasGroup *new_group) -{ - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - g_return_if_fail (FOO_IS_CANVAS_GROUP (new_group)); - - /* Both items need to be in the same canvas */ - g_return_if_fail (item->canvas == FOO_CANVAS_ITEM (new_group)->canvas); - - /* The group cannot be an inferior of the item or be the item itself -- - * this also takes care of the case where the item is the root item of - * the canvas. */ - g_return_if_fail (!is_descendant (FOO_CANVAS_ITEM (new_group), item)); - - /* Everything is ok, now actually reparent the item */ - - g_object_ref (GTK_OBJECT (item)); /* protect it from the unref in group_remove */ - - foo_canvas_item_request_redraw (item); - - group_remove (FOO_CANVAS_GROUP (item->parent), item); - item->parent = FOO_CANVAS_ITEM (new_group); - group_add (new_group, item); - - /* Redraw and repick */ - - redraw_and_repick_if_mapped (item); - - g_object_unref (GTK_OBJECT (item)); -} - -/** - * foo_canvas_item_grab_focus: - * @item: A canvas item. - * - * Makes the specified item take the keyboard focus, so all keyboard events will - * be sent to it. If the canvas widget itself did not have the focus, it grabs - * it as well. - **/ -void -foo_canvas_item_grab_focus (FooCanvasItem *item) -{ - FooCanvasItem *focused_item; - GdkEvent ev; - - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - g_return_if_fail (GTK_WIDGET_CAN_FOCUS (GTK_WIDGET (item->canvas))); - - focused_item = item->canvas->focused_item; - - if (focused_item) { - ev.focus_change.type = GDK_FOCUS_CHANGE; - ev.focus_change.window = GTK_LAYOUT (item->canvas)->bin_window; - ev.focus_change.send_event = FALSE; - ev.focus_change.in = FALSE; - - emit_event (item->canvas, &ev); - } - - item->canvas->focused_item = item; - gtk_widget_grab_focus (GTK_WIDGET (item->canvas)); - - if (focused_item) { - ev.focus_change.type = GDK_FOCUS_CHANGE; - ev.focus_change.window = GTK_LAYOUT (item->canvas)->bin_window; - ev.focus_change.send_event = FALSE; - ev.focus_change.in = TRUE; - - emit_event (item->canvas, &ev); - } -} - - -/** - * foo_canvas_item_get_bounds: - * @item: A canvas item. - * @x1: Leftmost edge of the bounding box (return value). - * @y1: Upper edge of the bounding box (return value). - * @x2: Rightmost edge of the bounding box (return value). - * @y2: Lower edge of the bounding box (return value). - * - * Queries the bounding box of a canvas item. The bounds are returned in the - * coordinate system of the item's parent. - **/ -void -foo_canvas_item_get_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2) -{ - double tx1, ty1, tx2, ty2; - - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - - tx1 = ty1 = tx2 = ty2 = 0.0; - - /* Get the item's bounds in its coordinate system */ - - if (FOO_CANVAS_ITEM_GET_CLASS (item)->bounds) - (* FOO_CANVAS_ITEM_GET_CLASS (item)->bounds) (item, &tx1, &ty1, &tx2, &ty2); - - /* Return the values */ - - if (x1) - *x1 = tx1; - - if (y1) - *y1 = ty1; - - if (x2) - *x2 = tx2; - - if (y2) - *y2 = ty2; -} - - -/** - * foo_canvas_item_request_update - * @item: A canvas item. - * - * To be used only by item implementations. Requests that the canvas queue an - * update for the specified item. - **/ -void -foo_canvas_item_request_update (FooCanvasItem *item) -{ - g_return_if_fail (!item->canvas->doing_update); - - if (item->object.flags & FOO_CANVAS_ITEM_NEED_UPDATE) - return; - - item->object.flags |= FOO_CANVAS_ITEM_NEED_UPDATE; - - if (item->parent != NULL) { - /* Recurse up the tree */ - foo_canvas_item_request_update (item->parent); - } else { - /* Have reached the top of the tree, make sure the update call gets scheduled. */ - foo_canvas_request_update (item->canvas); - } -} - -/** - * foo_canvas_item_request_update - * @item: A canvas item. - * - * Convenience function that informs a canvas that the specified item needs - * to be repainted. To be used by item implementations - **/ -void -foo_canvas_item_request_redraw (FooCanvasItem *item) -{ - if (item->object.flags & FOO_CANVAS_ITEM_MAPPED) - foo_canvas_request_redraw (item->canvas, - item->x1, item->y1, - item->x2 + 1, item->y2 + 1); -} - - - -/*** FooCanvasGroup ***/ - - -enum { - GROUP_PROP_0, - GROUP_PROP_X, - GROUP_PROP_Y -}; - - -static void foo_canvas_group_class_init (FooCanvasGroupClass *class); -static void foo_canvas_group_init (FooCanvasGroup *group); -static void foo_canvas_group_set_property(GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec); -static void foo_canvas_group_get_property(GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec); - -static void foo_canvas_group_destroy (GtkObject *object); - -static void foo_canvas_group_update (FooCanvasItem *item, - double i2w_dx, - double i2w_dy, - int flags); -static void foo_canvas_group_unrealize (FooCanvasItem *item); -static void foo_canvas_group_map (FooCanvasItem *item); -static void foo_canvas_group_unmap (FooCanvasItem *item); -static void foo_canvas_group_draw (FooCanvasItem *item, GdkDrawable *drawable, - GdkEventExpose *expose); -static double foo_canvas_group_point (FooCanvasItem *item, double x, double y, - int cx, int cy, - FooCanvasItem **actual_item); -static void foo_canvas_group_translate (FooCanvasItem *item, double dx, double dy); -static void foo_canvas_group_bounds (FooCanvasItem *item, double *x1, double *y1, - double *x2, double *y2); - - -static FooCanvasItemClass *group_parent_class; - - -/** - * foo_canvas_group_get_type: - * - * Registers the &FooCanvasGroup class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &FooCanvasGroup class. - **/ -GType -foo_canvas_group_get_type (void) -{ - static GType group_type = 0; - - if (!group_type) { - static const GTypeInfo group_info = { - sizeof (FooCanvasGroupClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) foo_canvas_group_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (FooCanvasGroup), - 0, /* n_preallocs */ - (GInstanceInitFunc) foo_canvas_group_init - - - }; - - group_type = g_type_register_static (foo_canvas_item_get_type (), - "FooCanvasGroup", - &group_info, - 0); - } - - return group_type; -} - -/* Class initialization function for FooCanvasGroupClass */ -static void -foo_canvas_group_class_init (FooCanvasGroupClass *class) -{ - GObjectClass *gobject_class; - GtkObjectClass *object_class; - FooCanvasItemClass *item_class; - - gobject_class = (GObjectClass *) class; - object_class = (GtkObjectClass *) class; - item_class = (FooCanvasItemClass *) class; - - group_parent_class = gtk_type_class (foo_canvas_item_get_type ()); - - gobject_class->set_property = foo_canvas_group_set_property; - gobject_class->get_property = foo_canvas_group_get_property; - - g_object_class_install_property - (gobject_class, GROUP_PROP_X, - g_param_spec_double ("x", - _("X"), - _("X"), - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - g_object_class_install_property - (gobject_class, GROUP_PROP_Y, - g_param_spec_double ("y", - _("Y"), - _("Y"), - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - - object_class->destroy = foo_canvas_group_destroy; - - item_class->update = foo_canvas_group_update; - item_class->unrealize = foo_canvas_group_unrealize; - item_class->map = foo_canvas_group_map; - item_class->unmap = foo_canvas_group_unmap; - item_class->draw = foo_canvas_group_draw; - item_class->point = foo_canvas_group_point; - item_class->translate = foo_canvas_group_translate; - item_class->bounds = foo_canvas_group_bounds; -} - -/* Object initialization function for FooCanvasGroup */ -static void -foo_canvas_group_init (FooCanvasGroup *group) -{ - group->xpos = 0.0; - group->ypos = 0.0; -} - -/* Set_property handler for canvas groups */ -static void -foo_canvas_group_set_property (GObject *gobject, guint param_id, - const GValue *value, GParamSpec *pspec) -{ - FooCanvasItem *item; - FooCanvasGroup *group; - double old; - gboolean moved; - - g_return_if_fail (FOO_IS_CANVAS_GROUP (gobject)); - - item = FOO_CANVAS_ITEM (gobject); - group = FOO_CANVAS_GROUP (gobject); - - moved = FALSE; - switch (param_id) { - case GROUP_PROP_X: - old = group->xpos; - group->xpos = g_value_get_double (value); - if (old != group->xpos) - moved = TRUE; - break; - - case GROUP_PROP_Y: - old = group->ypos; - group->ypos = g_value_get_double (value); - if (old != group->ypos) - moved = TRUE; - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec); - break; - } - - if (moved) { - item->object.flags |= FOO_CANVAS_ITEM_NEED_DEEP_UPDATE; - if (item->parent != NULL) - foo_canvas_item_request_update (item->parent); - else - foo_canvas_request_update (item->canvas); - } -} - -/* Get_property handler for canvas groups */ -static void -foo_canvas_group_get_property (GObject *gobject, guint param_id, - GValue *value, GParamSpec *pspec) -{ - FooCanvasItem *item; - FooCanvasGroup *group; - - g_return_if_fail (FOO_IS_CANVAS_GROUP (gobject)); - - item = FOO_CANVAS_ITEM (gobject); - group = FOO_CANVAS_GROUP (gobject); - - switch (param_id) { - case GROUP_PROP_X: - g_value_set_double (value, group->xpos); - break; - - case GROUP_PROP_Y: - g_value_set_double (value, group->ypos); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec); - break; - } -} - -/* Destroy handler for canvas groups */ -static void -foo_canvas_group_destroy (GtkObject *object) -{ - FooCanvasGroup *group; - FooCanvasItem *child; - GList *list; - - g_return_if_fail (FOO_IS_CANVAS_GROUP (object)); - - group = FOO_CANVAS_GROUP (object); - - list = group->item_list; - while (list) { - child = list->data; - list = list->next; - - gtk_object_destroy (GTK_OBJECT (child)); - } - - if (GTK_OBJECT_CLASS (group_parent_class)->destroy) - (* GTK_OBJECT_CLASS (group_parent_class)->destroy) (object); -} - -/* Update handler for canvas groups */ -static void -foo_canvas_group_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags) -{ - FooCanvasGroup *group; - GList *list; - FooCanvasItem *i; - double bbox_x0, bbox_y0, bbox_x1, bbox_y1; - gboolean first = TRUE; - - group = FOO_CANVAS_GROUP (item); - - (* group_parent_class->update) (item, i2w_dx, i2w_dy, flags); - - bbox_x0 = 0; - bbox_y0 = 0; - bbox_x1 = 0; - bbox_y1 = 0; - - for (list = group->item_list; list; list = list->next) { - i = list->data; - - foo_canvas_item_invoke_update (i, i2w_dx + group->xpos, i2w_dy + group->ypos, flags); - - if (first) { - first = FALSE; - bbox_x0 = i->x1; - bbox_y0 = i->y1; - bbox_x1 = i->x2; - bbox_y1 = i->y2; - } else { - bbox_x0 = MIN (bbox_x0, i->x1); - bbox_y0 = MIN (bbox_y0, i->y1); - bbox_x1 = MAX (bbox_x1, i->x2); - bbox_y1 = MAX (bbox_y1, i->y2); - } - } - item->x1 = bbox_x0; - item->y1 = bbox_y0; - item->x2 = bbox_x1; - item->y2 = bbox_y1; -} - -/* Unrealize handler for canvas groups */ -static void -foo_canvas_group_unrealize (FooCanvasItem *item) -{ - FooCanvasGroup *group; - GList *list; - FooCanvasItem *i; - - group = FOO_CANVAS_GROUP (item); - - /* Unmap group before children to avoid flash */ - if (item->object.flags & FOO_CANVAS_ITEM_MAPPED) - (* FOO_CANVAS_ITEM_GET_CLASS (item)->unmap) (item); - - for (list = group->item_list; list; list = list->next) { - i = list->data; - - if (i->object.flags & FOO_CANVAS_ITEM_REALIZED) - (* FOO_CANVAS_ITEM_GET_CLASS (i)->unrealize) (i); - } - - (* group_parent_class->unrealize) (item); -} - -/* Map handler for canvas groups */ -static void -foo_canvas_group_map (FooCanvasItem *item) -{ - FooCanvasGroup *group; - GList *list; - FooCanvasItem *i; - - group = FOO_CANVAS_GROUP (item); - - for (list = group->item_list; list; list = list->next) { - i = list->data; - - if (i->object.flags & FOO_CANVAS_ITEM_VISIBLE && - !(i->object.flags & FOO_CANVAS_ITEM_MAPPED)) { - if (!(i->object.flags & FOO_CANVAS_ITEM_REALIZED)) - (* FOO_CANVAS_ITEM_GET_CLASS (i)->realize) (i); - - (* FOO_CANVAS_ITEM_GET_CLASS (i)->map) (i); - } - } - - (* group_parent_class->map) (item); -} - -/* Unmap handler for canvas groups */ -static void -foo_canvas_group_unmap (FooCanvasItem *item) -{ - FooCanvasGroup *group; - GList *list; - FooCanvasItem *i; - - group = FOO_CANVAS_GROUP (item); - - for (list = group->item_list; list; list = list->next) { - i = list->data; - - if (i->object.flags & FOO_CANVAS_ITEM_MAPPED) - (* FOO_CANVAS_ITEM_GET_CLASS (i)->unmap) (i); - } - - (* group_parent_class->unmap) (item); -} - -/* Draw handler for canvas groups */ -static void -foo_canvas_group_draw (FooCanvasItem *item, GdkDrawable *drawable, - GdkEventExpose *expose) -{ - FooCanvasGroup *group; - GList *list; - FooCanvasItem *child = NULL; - - group = FOO_CANVAS_GROUP (item); - - for (list = group->item_list; list; list = list->next) { - child = list->data; - - if ((child->object.flags & FOO_CANVAS_ITEM_MAPPED) && - (FOO_CANVAS_ITEM_GET_CLASS (child)->draw)) { - GdkRectangle child_rect; - - child_rect.x = child->x1; - child_rect.y = child->y1; - child_rect.width = child->x2 - child->x1 + 1; - child_rect.height = child->y2 - child->y1 + 1; - - if (gdk_region_rect_in (expose->region, &child_rect) != GDK_OVERLAP_RECTANGLE_OUT) - (* FOO_CANVAS_ITEM_GET_CLASS (child)->draw) (child, drawable, expose); - } - } -} - -/* Point handler for canvas groups */ -static double -foo_canvas_group_point (FooCanvasItem *item, double x, double y, int cx, int cy, - FooCanvasItem **actual_item) -{ - FooCanvasGroup *group; - GList *list; - FooCanvasItem *child, *point_item; - int x1, y1, x2, y2; - double gx, gy; - double dist, best; - int has_point; - - group = FOO_CANVAS_GROUP (item); - - x1 = cx - item->canvas->close_enough; - y1 = cy - item->canvas->close_enough; - x2 = cx + item->canvas->close_enough; - y2 = cy + item->canvas->close_enough; - - best = 0.0; - *actual_item = NULL; - - gx = x - group->xpos; - gy = y - group->ypos; - - dist = 0.0; /* keep gcc happy */ - - for (list = group->item_list; list; list = list->next) { - child = list->data; - - if ((child->x1 > x2) || (child->y1 > y2) || (child->x2 < x1) || (child->y2 < y1)) - continue; - - point_item = NULL; /* cater for incomplete item implementations */ - - if ((child->object.flags & FOO_CANVAS_ITEM_MAPPED) - && FOO_CANVAS_ITEM_GET_CLASS (child)->point) { - dist = foo_canvas_item_invoke_point (child, gx, gy, cx, cy, &point_item); - has_point = TRUE; - } else - has_point = FALSE; - /* guessing that the x factor is OK here. RNGC */ - if (has_point - && point_item - && ((int) (dist * item->canvas->pixels_per_unit_x + 0.5) - <= item->canvas->close_enough)) { - best = dist; - *actual_item = point_item; - } - } - - return best; -} - -void -foo_canvas_group_translate (FooCanvasItem *item, double dx, double dy) -{ - FooCanvasGroup *group; - - group = FOO_CANVAS_GROUP (item); - - group->xpos += dx; - group->ypos += dy; -} - -/* Bounds handler for canvas groups */ -static void -foo_canvas_group_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2) -{ - FooCanvasGroup *group; - FooCanvasItem *child; - GList *list; - double tx1, ty1, tx2, ty2; - double minx, miny, maxx, maxy; - int set; - - group = FOO_CANVAS_GROUP (item); - - /* Get the bounds of the first visible item */ - - child = NULL; /* Unnecessary but eliminates a warning. */ - - set = FALSE; - - for (list = group->item_list; list; list = list->next) { - child = list->data; - - if (child->object.flags & FOO_CANVAS_ITEM_MAPPED) { - set = TRUE; - foo_canvas_item_get_bounds (child, &minx, &miny, &maxx, &maxy); - break; - } - } - - /* If there were no visible items, return an empty bounding box */ - - if (!set) { - *x1 = *y1 = *x2 = *y2 = 0.0; - return; - } - - /* Now we can grow the bounds using the rest of the items */ - - list = list->next; - - for (; list; list = list->next) { - child = list->data; - - if (!(child->object.flags & FOO_CANVAS_ITEM_MAPPED)) - continue; - - foo_canvas_item_get_bounds (child, &tx1, &ty1, &tx2, &ty2); - - if (tx1 < minx) - minx = tx1; - - if (ty1 < miny) - miny = ty1; - - if (tx2 > maxx) - maxx = tx2; - - if (ty2 > maxy) - maxy = ty2; - } - - /* Make the bounds be relative to our parent's coordinate system */ - - if (item->parent) { - minx += group->xpos; - miny += group->ypos; - maxx += group->xpos; - maxy += group->ypos; - } - - *x1 = minx; - *y1 = miny; - *x2 = maxx; - *y2 = maxy; -} - -/* Adds an item to a group */ -static void -group_add (FooCanvasGroup *group, FooCanvasItem *item) -{ - g_object_ref (GTK_OBJECT (item)); - gtk_object_sink (GTK_OBJECT (item)); - - if (!group->item_list) { - group->item_list = g_list_append (group->item_list, item); - group->item_list_end = group->item_list; - } else - group->item_list_end = g_list_append (group->item_list_end, item)->next; - - if (item->object.flags & FOO_CANVAS_ITEM_VISIBLE && - group->item.object.flags & FOO_CANVAS_ITEM_MAPPED) { - if (!(item->object.flags & FOO_CANVAS_ITEM_REALIZED)) - (* FOO_CANVAS_ITEM_GET_CLASS (item)->realize) (item); - - if (!(item->object.flags & FOO_CANVAS_ITEM_MAPPED)) - (* FOO_CANVAS_ITEM_GET_CLASS (item)->map) (item); - } -} - -/* Removes an item from a group */ -static void -group_remove (FooCanvasGroup *group, FooCanvasItem *item) -{ - GList *children; - - g_return_if_fail (FOO_IS_CANVAS_GROUP (group)); - g_return_if_fail (FOO_IS_CANVAS_ITEM (item)); - - for (children = group->item_list; children; children = children->next) - if (children->data == item) { - if (item->object.flags & FOO_CANVAS_ITEM_MAPPED) - (* FOO_CANVAS_ITEM_GET_CLASS (item)->unmap) (item); - - if (item->object.flags & FOO_CANVAS_ITEM_REALIZED) - (* FOO_CANVAS_ITEM_GET_CLASS (item)->unrealize) (item); - - /* Unparent the child */ - - item->parent = NULL; - g_object_unref (GTK_OBJECT (item)); - - /* Remove it from the list */ - - if (children == group->item_list_end) - group->item_list_end = children->prev; - - group->item_list = g_list_remove_link (group->item_list, children); - g_list_free (children); - break; - } -} - - -/*** FooCanvas ***/ - - -enum { - DRAW_BACKGROUND, - LAST_SIGNAL -}; - -static void foo_canvas_class_init (FooCanvasClass *class); -static void foo_canvas_init (FooCanvas *canvas); -static void foo_canvas_destroy (GtkObject *object); -static void foo_canvas_map (GtkWidget *widget); -static void foo_canvas_unmap (GtkWidget *widget); -static void foo_canvas_realize (GtkWidget *widget); -static void foo_canvas_unrealize (GtkWidget *widget); -static void foo_canvas_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static gint foo_canvas_button (GtkWidget *widget, - GdkEventButton *event); -static gint foo_canvas_motion (GtkWidget *widget, - GdkEventMotion *event); -static gint foo_canvas_expose (GtkWidget *widget, - GdkEventExpose *event); -static gint foo_canvas_key (GtkWidget *widget, - GdkEventKey *event); -static gint foo_canvas_crossing (GtkWidget *widget, - GdkEventCrossing *event); -static gint foo_canvas_focus_in (GtkWidget *widget, - GdkEventFocus *event); -static gint foo_canvas_focus_out (GtkWidget *widget, - GdkEventFocus *event); -static void foo_canvas_request_update_real (FooCanvas *canvas); -static void foo_canvas_draw_background (FooCanvas *canvas, - int x, - int y, - int width, - int height); - - -static GtkLayoutClass *canvas_parent_class; - -static guint canvas_signals[LAST_SIGNAL]; - -/** - * foo_canvas_get_type: - * - * Registers the &FooCanvas class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the &FooCanvas class. - **/ -GType -foo_canvas_get_type (void) -{ - static GType canvas_type = 0; - - if (!canvas_type) { - static const GTypeInfo canvas_info = { - sizeof (FooCanvasClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) foo_canvas_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (FooCanvas), - 0, /* n_preallocs */ - (GInstanceInitFunc) foo_canvas_init - }; - - canvas_type = g_type_register_static (gtk_layout_get_type (), - "FooCanvas", - &canvas_info, - 0); - } - - return canvas_type; -} - -static void -foo_canvas_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -foo_canvas_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -foo_canvas_accessible_adjustment_changed (GtkAdjustment *adjustment, - gpointer data) -{ - AtkObject *atk_obj; - - /* The scrollbars have changed */ - atk_obj = ATK_OBJECT (data); - - g_signal_emit_by_name (atk_obj, "visible_data_changed"); -} - -static void -foo_canvas_accessible_initialize (AtkObject *obj, - gpointer data) -{ - FooCanvas *canvas; - - if (ATK_OBJECT_CLASS (accessible_parent_class)->initialize != NULL) - ATK_OBJECT_CLASS (accessible_parent_class)->initialize (obj, data); - - canvas = FOO_CANVAS (data); - g_signal_connect (canvas->layout.hadjustment, - "value_changed", - G_CALLBACK (foo_canvas_accessible_adjustment_changed), - obj); - g_signal_connect (canvas->layout.vadjustment, - "value_changed", - G_CALLBACK (foo_canvas_accessible_adjustment_changed), - obj); - - obj->role = ATK_ROLE_LAYERED_PANE; -} - -static gint -foo_canvas_accessible_get_n_children (AtkObject* obj) -{ - GtkAccessible *accessible; - GtkWidget *widget; - FooCanvas *canvas; - FooCanvasGroup *root_group; - - accessible = GTK_ACCESSIBLE (obj); - widget = accessible->widget; - if (widget == NULL) { - /* State is defunct */ - return 0; - } - - g_return_val_if_fail (FOO_IS_CANVAS (widget), 0); - - canvas = FOO_CANVAS (widget); - root_group = foo_canvas_root (canvas); - g_return_val_if_fail (root_group, 0); - return 1; -} - -static AtkObject* -foo_canvas_accessible_ref_child (AtkObject *obj, - gint i) -{ - GtkAccessible *accessible; - GtkWidget *widget; - FooCanvas *canvas; - FooCanvasGroup *root_group; - AtkObject *atk_object; - - /* Canvas only has one child, so return NULL if index is non zero */ - if (i != 0) { - return NULL; - } - - accessible = GTK_ACCESSIBLE (obj); - widget = accessible->widget; - if (widget == NULL) { - /* State is defunct */ - return NULL; - } - - canvas = FOO_CANVAS (widget); - root_group = foo_canvas_root (canvas); - g_return_val_if_fail (root_group, NULL); - atk_object = atk_gobject_accessible_for_object (G_OBJECT (root_group)); - g_object_ref (atk_object); - - g_warning ("Accessible support for FooGroup needs to be implemented"); - - return atk_object; -} - -static void -foo_canvas_accessible_class_init (AtkObjectClass *klass) -{ - accessible_parent_class = g_type_class_peek_parent (klass); - - klass->initialize = foo_canvas_accessible_initialize; - klass->get_n_children = foo_canvas_accessible_get_n_children; - klass->ref_child = foo_canvas_accessible_ref_child; -} - -static GType -foo_canvas_accessible_get_type (void) -{ - static GType type = 0; - - if (!type) { - AtkObjectFactory *factory; - GType parent_atk_type; - GTypeQuery query; - GTypeInfo tinfo = { 0 }; - - factory = atk_registry_get_factory (atk_get_default_registry(), - GTK_TYPE_WIDGET); - if (!factory) { - return G_TYPE_INVALID; - } - parent_atk_type = atk_object_factory_get_accessible_type (factory); - if (!parent_atk_type) { - return G_TYPE_INVALID; - } - g_type_query (parent_atk_type, &query); - tinfo.class_init = (GClassInitFunc) foo_canvas_accessible_class_init; - tinfo.class_size = query.class_size; - tinfo.instance_size = query.instance_size; - type = g_type_register_static (parent_atk_type, - "FooCanvasAccessibility", - &tinfo, 0); - } - return type; -} - -static AtkObject * -foo_canvas_accessible_create (GObject *for_object) -{ - GType type; - AtkObject *accessible; - FooCanvas *canvas; - - canvas = FOO_CANVAS (for_object); - g_return_val_if_fail (canvas != NULL, NULL); - - type = foo_canvas_accessible_get_type (); - - if (type == G_TYPE_INVALID) { - return atk_no_op_object_new (for_object); - } - - accessible = g_object_new (type, NULL); - atk_object_initialize (accessible, for_object); - return accessible; -} - -static GType -foo_canvas_accessible_factory_get_accessible_type (void) -{ - return foo_canvas_accessible_get_type (); -} - -static AtkObject* -foo_canvas_accessible_factory_create_accessible (GObject *obj) -{ - AtkObject *accessible; - - g_return_val_if_fail (G_IS_OBJECT (obj), NULL); - - accessible = foo_canvas_accessible_create (obj); - - return accessible; -} - -static void -foo_canvas_accessible_factory_class_init (AtkObjectFactoryClass *klass) -{ - klass->create_accessible = foo_canvas_accessible_factory_create_accessible; - klass->get_accessible_type = foo_canvas_accessible_factory_get_accessible_type; -} - -static GType -foo_canvas_accessible_factory_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo tinfo = { - sizeof (AtkObjectFactoryClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) foo_canvas_accessible_factory_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (AtkObjectFactory), - 0, /* n_preallocs */ - NULL - }; - type = g_type_register_static (ATK_TYPE_OBJECT_FACTORY, - "FooCanvasAccessibilityFactory", - &tinfo, 0); - } - - return type; -} - - -/* Class initialization function for FooCanvasClass */ -static void -foo_canvas_class_init (FooCanvasClass *klass) -{ - GObjectClass *gobject_class; - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - gobject_class = (GObjectClass *)klass; - object_class = (GtkObjectClass *) klass; - widget_class = (GtkWidgetClass *) klass; - - canvas_parent_class = gtk_type_class (gtk_layout_get_type ()); - - gobject_class->set_property = foo_canvas_set_property; - gobject_class->get_property = foo_canvas_get_property; - - object_class->destroy = foo_canvas_destroy; - - widget_class->map = foo_canvas_map; - widget_class->unmap = foo_canvas_unmap; - widget_class->realize = foo_canvas_realize; - widget_class->unrealize = foo_canvas_unrealize; - widget_class->size_allocate = foo_canvas_size_allocate; - widget_class->button_press_event = foo_canvas_button; - widget_class->button_release_event = foo_canvas_button; - widget_class->motion_notify_event = foo_canvas_motion; - widget_class->expose_event = foo_canvas_expose; - widget_class->key_press_event = foo_canvas_key; - widget_class->key_release_event = foo_canvas_key; - widget_class->enter_notify_event = foo_canvas_crossing; - widget_class->leave_notify_event = foo_canvas_crossing; - widget_class->focus_in_event = foo_canvas_focus_in; - widget_class->focus_out_event = foo_canvas_focus_out; - - klass->draw_background = foo_canvas_draw_background; - klass->request_update = foo_canvas_request_update_real; - - canvas_signals[DRAW_BACKGROUND] = - g_signal_new ("draw_background", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (FooCanvasClass, draw_background), - NULL, NULL, - foo_canvas_marshal_VOID__INT_INT_INT_INT, - G_TYPE_NONE, 4, - G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT); - - atk_registry_set_factory_type (atk_get_default_registry (), - FOO_TYPE_CANVAS, - foo_canvas_accessible_factory_get_type ()); -} - -/* Callback used when the root item of a canvas is destroyed. The user should - * never ever do this, so we panic if this happens. - */ -static void -panic_root_destroyed (GtkObject *object, gpointer data) -{ - g_error ("Eeeek, root item %p of canvas %p was destroyed!", object, data); -} - -/* Object initialization function for FooCanvas */ -static void -foo_canvas_init (FooCanvas *canvas) -{ - GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_FOCUS); - - gtk_widget_set_redraw_on_allocate (GTK_WIDGET (canvas), FALSE); - - canvas->scroll_x1 = 0.0; - canvas->scroll_y1 = 0.0; - canvas->scroll_x2 = canvas->layout.width; - canvas->scroll_y2 = canvas->layout.height; - - canvas->pixels_per_unit_x = 1.0; - canvas->pixels_per_unit_y = 1.0; - - canvas->pick_event.type = GDK_LEAVE_NOTIFY; - canvas->pick_event.crossing.x = 0; - canvas->pick_event.crossing.y = 0; - - gtk_layout_set_hadjustment (GTK_LAYOUT (canvas), NULL); - gtk_layout_set_vadjustment (GTK_LAYOUT (canvas), NULL); - - /* Create the root item as a special case */ - - canvas->root = FOO_CANVAS_ITEM (g_object_new (foo_canvas_group_get_type (), NULL)); - canvas->root->canvas = canvas; - - g_object_ref (GTK_OBJECT (canvas->root)); - gtk_object_sink (GTK_OBJECT (canvas->root)); - - canvas->root_destroy_id = g_signal_connect (GTK_OBJECT (canvas->root), "destroy", - (GtkSignalFunc) panic_root_destroyed, - canvas); - - canvas->need_repick = TRUE; - canvas->doing_update = FALSE; -} - -/* Convenience function to remove the idle handler of a canvas */ -static void -remove_idle (FooCanvas *canvas) -{ - if (canvas->idle_id == 0) - return; - - g_source_remove (canvas->idle_id); - canvas->idle_id = 0; -} - -/* Removes the transient state of the canvas (idle handler, grabs). */ -static void -shutdown_transients (FooCanvas *canvas) -{ - /* We turn off the need_redraw flag, since if the canvas is mapped again - * it will request a redraw anyways. We do not turn off the need_update - * flag, though, because updates are not queued when the canvas remaps - * itself. - */ - if (canvas->need_redraw) { - canvas->need_redraw = FALSE; - } - - if (canvas->grabbed_item) { - GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (canvas)); - canvas->grabbed_item = NULL; - gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME); - } - - remove_idle (canvas); -} - -/* Destroy handler for FooCanvas */ -static void -foo_canvas_destroy (GtkObject *object) -{ - FooCanvas *canvas; - - g_return_if_fail (FOO_IS_CANVAS (object)); - - /* remember, destroy can be run multiple times! */ - - canvas = FOO_CANVAS (object); - - if (canvas->root_destroy_id) { - g_signal_handler_disconnect (GTK_OBJECT (canvas->root), canvas->root_destroy_id); - canvas->root_destroy_id = 0; - } - if (canvas->root) { - g_object_unref (GTK_OBJECT (canvas->root)); - canvas->root = NULL; - } - - shutdown_transients (canvas); - - if (GTK_OBJECT_CLASS (canvas_parent_class)->destroy) - (* GTK_OBJECT_CLASS (canvas_parent_class)->destroy) (object); -} - -/** - * foo_canvas_new: - * @void: - * - * Creates a new empty canvas. If you wish to use the - * &FooCanvasImage item inside this canvas, then you must push the gdk_imlib - * visual and colormap before calling this function, and they can be popped - * afterwards. - * - * Return value: A newly-created canvas. - **/ -GtkWidget * -foo_canvas_new (void) -{ - return GTK_WIDGET (g_object_new (foo_canvas_get_type (), NULL)); -} - -/* Map handler for the canvas */ -static void -foo_canvas_map (GtkWidget *widget) -{ - FooCanvas *canvas; - - g_return_if_fail (FOO_IS_CANVAS (widget)); - - /* Normal widget mapping stuff */ - - if (GTK_WIDGET_CLASS (canvas_parent_class)->map) - (* GTK_WIDGET_CLASS (canvas_parent_class)->map) (widget); - - canvas = FOO_CANVAS (widget); - - /* Map items */ - - if (canvas->root->object.flags & FOO_CANVAS_ITEM_VISIBLE && - !(canvas->root->object.flags & FOO_CANVAS_ITEM_MAPPED) && - FOO_CANVAS_ITEM_GET_CLASS (canvas->root)->map) - (* FOO_CANVAS_ITEM_GET_CLASS (canvas->root)->map) (canvas->root); -} - -/* Unmap handler for the canvas */ -static void -foo_canvas_unmap (GtkWidget *widget) -{ - FooCanvas *canvas; - - g_return_if_fail (FOO_IS_CANVAS (widget)); - - canvas = FOO_CANVAS (widget); - - shutdown_transients (canvas); - - /* Unmap items */ - - if (FOO_CANVAS_ITEM_GET_CLASS (canvas->root)->unmap) - (* FOO_CANVAS_ITEM_GET_CLASS (canvas->root)->unmap) (canvas->root); - - /* Normal widget unmapping stuff */ - - if (GTK_WIDGET_CLASS (canvas_parent_class)->unmap) - (* GTK_WIDGET_CLASS (canvas_parent_class)->unmap) (widget); -} - -/* Realize handler for the canvas */ -static void -foo_canvas_realize (GtkWidget *widget) -{ - FooCanvas *canvas; - - g_return_if_fail (FOO_IS_CANVAS (widget)); - - /* Normal widget realization stuff */ - - if (GTK_WIDGET_CLASS (canvas_parent_class)->realize) - (* GTK_WIDGET_CLASS (canvas_parent_class)->realize) (widget); - - canvas = FOO_CANVAS (widget); - - gdk_window_set_events (canvas->layout.bin_window, - (gdk_window_get_events (canvas->layout.bin_window) - | GDK_EXPOSURE_MASK - | GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK - | GDK_POINTER_MOTION_MASK - | GDK_KEY_PRESS_MASK - | GDK_KEY_RELEASE_MASK - | GDK_ENTER_NOTIFY_MASK - | GDK_LEAVE_NOTIFY_MASK - | GDK_FOCUS_CHANGE_MASK)); - - /* Create our own temporary pixmap gc and realize all the items */ - - canvas->pixmap_gc = gdk_gc_new (canvas->layout.bin_window); - - (* FOO_CANVAS_ITEM_GET_CLASS (canvas->root)->realize) (canvas->root); -} - -/* Unrealize handler for the canvas */ -static void -foo_canvas_unrealize (GtkWidget *widget) -{ - FooCanvas *canvas; - - g_return_if_fail (FOO_IS_CANVAS (widget)); - - canvas = FOO_CANVAS (widget); - - shutdown_transients (canvas); - - /* Unrealize items and parent widget */ - - (* FOO_CANVAS_ITEM_GET_CLASS (canvas->root)->unrealize) (canvas->root); - - g_object_unref (canvas->pixmap_gc); - canvas->pixmap_gc = NULL; - - if (GTK_WIDGET_CLASS (canvas_parent_class)->unrealize) - (* GTK_WIDGET_CLASS (canvas_parent_class)->unrealize) (widget); -} - -/* Handles scrolling of the canvas. Adjusts the scrolling and zooming offset to - * keep as much as possible of the canvas scrolling region in view. - */ -static void -scroll_to (FooCanvas *canvas, int cx, int cy) -{ - int scroll_width, scroll_height; - int right_limit, bottom_limit; - int old_zoom_xofs, old_zoom_yofs; - int changed_x = FALSE, changed_y = FALSE; - int canvas_width, canvas_height; - - canvas_width = GTK_WIDGET (canvas)->allocation.width; - canvas_height = GTK_WIDGET (canvas)->allocation.height; - - scroll_width = floor ((canvas->scroll_x2 - canvas->scroll_x1) * canvas->pixels_per_unit_x + 0.5); - scroll_height = floor ((canvas->scroll_y2 - canvas->scroll_y1) * canvas->pixels_per_unit_y + 0.5); - - right_limit = scroll_width - canvas_width; - bottom_limit = scroll_height - canvas_height; - - old_zoom_xofs = canvas->zoom_xofs; - old_zoom_yofs = canvas->zoom_yofs; - - if (right_limit < 0) { - cx = 0; - if (canvas->center_scroll_region) { - canvas->zoom_xofs = (canvas_width - scroll_width) / 2; - scroll_width = canvas_width; - } else { - canvas->zoom_xofs = 0; - } - } else if (cx < 0) { - cx = 0; - canvas->zoom_xofs = 0; - } else if (cx > right_limit) { - cx = right_limit; - canvas->zoom_xofs = 0; - } else - canvas->zoom_xofs = 0; - - if (bottom_limit < 0) { - cy = 0; - if (canvas->center_scroll_region) { - canvas->zoom_yofs = (canvas_height - scroll_height) / 2; - scroll_height = canvas_height; - } else { - canvas->zoom_yofs = 0; - } - } else if (cy < 0) { - cy = 0; - canvas->zoom_yofs = 0; - } else if (cy > bottom_limit) { - cy = bottom_limit; - canvas->zoom_yofs = 0; - } else - canvas->zoom_yofs = 0; - - if ((canvas->zoom_xofs != old_zoom_xofs) || (canvas->zoom_yofs != old_zoom_yofs)) { - /* This can only occur, if either canvas size or widget size changes */ - /* So I think we can request full redraw here */ - /* More stuff - we have to mark root as needing fresh affine (Lauris) */ - if (!(canvas->root->object.flags & FOO_CANVAS_ITEM_NEED_DEEP_UPDATE)) { - canvas->root->object.flags |= FOO_CANVAS_ITEM_NEED_DEEP_UPDATE; - foo_canvas_request_update (canvas); - } - gtk_widget_queue_draw (GTK_WIDGET (canvas)); - } - - if (((int) canvas->layout.hadjustment->value) != cx) { - canvas->layout.hadjustment->value = cx; - changed_x = TRUE; - } - - if (((int) canvas->layout.vadjustment->value) != cy) { - canvas->layout.vadjustment->value = cy; - changed_y = TRUE; - } - - if ((scroll_width != (int) canvas->layout.width) || (scroll_height != (int) canvas->layout.height)) { - gtk_layout_set_size (GTK_LAYOUT (canvas), scroll_width, scroll_height); - } - - /* Signal GtkLayout that it should do a redraw. */ - if (changed_x) - g_signal_emit_by_name (GTK_OBJECT (canvas->layout.hadjustment), "value_changed"); - if (changed_y) - g_signal_emit_by_name (GTK_OBJECT (canvas->layout.vadjustment), "value_changed"); -} - -/* Size allocation handler for the canvas */ -static void -foo_canvas_size_allocate (GtkWidget *widget, GtkAllocation *allocation) -{ - FooCanvas *canvas; - - g_return_if_fail (FOO_IS_CANVAS (widget)); - g_return_if_fail (allocation != NULL); - - if (GTK_WIDGET_CLASS (canvas_parent_class)->size_allocate) - (* GTK_WIDGET_CLASS (canvas_parent_class)->size_allocate) (widget, allocation); - - canvas = FOO_CANVAS (widget); - - /* Recenter the view, if appropriate */ - - canvas->layout.hadjustment->page_size = allocation->width; - canvas->layout.hadjustment->page_increment = allocation->width / 2; - - canvas->layout.vadjustment->page_size = allocation->height; - canvas->layout.vadjustment->page_increment = allocation->height / 2; - - scroll_to (canvas, - canvas->layout.hadjustment->value, - canvas->layout.vadjustment->value); - - g_signal_emit_by_name (GTK_OBJECT (canvas->layout.hadjustment), "changed"); - g_signal_emit_by_name (GTK_OBJECT (canvas->layout.vadjustment), "changed"); -} - -/* Emits an event for an item in the canvas, be it the current item, grabbed - * item, or focused item, as appropriate. - */ - -static int -emit_event (FooCanvas *canvas, GdkEvent *event) -{ - GdkEvent ev; - gint finished; - FooCanvasItem *item; - FooCanvasItem *parent; - guint mask; - - /* Could be an old pick event */ - if (!GTK_WIDGET_REALIZED (canvas)) { - return FALSE; - } - - /* Perform checks for grabbed items */ - - if (canvas->grabbed_item && - !is_descendant (canvas->current_item, canvas->grabbed_item)) { - return FALSE; - } - - if (canvas->grabbed_item) { - switch (event->type) { - case GDK_ENTER_NOTIFY: - mask = GDK_ENTER_NOTIFY_MASK; - break; - - case GDK_LEAVE_NOTIFY: - mask = GDK_LEAVE_NOTIFY_MASK; - break; - - case GDK_MOTION_NOTIFY: - mask = GDK_POINTER_MOTION_MASK; - break; - - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - mask = GDK_BUTTON_PRESS_MASK; - break; - - case GDK_BUTTON_RELEASE: - mask = GDK_BUTTON_RELEASE_MASK; - break; - - case GDK_KEY_PRESS: - mask = GDK_KEY_PRESS_MASK; - break; - - case GDK_KEY_RELEASE: - mask = GDK_KEY_RELEASE_MASK; - break; - - default: - mask = 0; - break; - } - - if (!(mask & canvas->grabbed_event_mask)) - return FALSE; - } - - /* Convert to world coordinates -- we have two cases because of diferent - * offsets of the fields in the event structures. - */ - - ev = *event; - - switch (ev.type) - { - case GDK_ENTER_NOTIFY: - case GDK_LEAVE_NOTIFY: - foo_canvas_window_to_world (canvas, - ev.crossing.x, ev.crossing.y, - &ev.crossing.x, &ev.crossing.y); - break; - - case GDK_MOTION_NOTIFY: - foo_canvas_window_to_world (canvas, - ev.motion.x, ev.motion.y, - &ev.motion.x, &ev.motion.y); - break; - - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - foo_canvas_window_to_world (canvas, - ev.motion.x, ev.motion.y, - &ev.motion.x, &ev.motion.y); - break; - - case GDK_BUTTON_RELEASE: - foo_canvas_window_to_world (canvas, - ev.motion.x, ev.motion.y, - &ev.motion.x, &ev.motion.y); - break; - - default: - break; - } - - /* Choose where we send the event */ - - item = canvas->current_item; - - if (canvas->focused_item - && ((event->type == GDK_KEY_PRESS) || - (event->type == GDK_KEY_RELEASE) || - (event->type == GDK_FOCUS_CHANGE))) - item = canvas->focused_item; - - /* The event is propagated up the hierarchy (for if someone connected to - * a group instead of a leaf event), and emission is stopped if a - * handler returns TRUE, just like for GtkWidget events. - */ - - finished = FALSE; - - while (item && !finished) { - g_object_ref (GTK_OBJECT (item)); - - g_signal_emit ( - GTK_OBJECT (item), item_signals[ITEM_EVENT], 0, - &ev, &finished); - - parent = item->parent; - g_object_unref (GTK_OBJECT (item)); - - item = parent; - } - - return finished; -} - -/* Re-picks the current item in the canvas, based on the event's coordinates. - * Also emits enter/leave events for items as appropriate. - */ -static int -pick_current_item (FooCanvas *canvas, GdkEvent *event) -{ - int button_down; - double x, y; - int cx, cy; - int retval; - - retval = FALSE; - - /* If a button is down, we'll perform enter and leave events on the - * current item, but not enter on any other item. This is more or less - * like X pointer grabbing for canvas items. - */ - button_down = canvas->state & (GDK_BUTTON1_MASK - | GDK_BUTTON2_MASK - | GDK_BUTTON3_MASK - | GDK_BUTTON4_MASK - | GDK_BUTTON5_MASK); - if (!button_down) - canvas->left_grabbed_item = FALSE; - - /* Save the event in the canvas. This is used to synthesize enter and - * leave events in case the current item changes. It is also used to - * re-pick the current item if the current one gets deleted. Also, - * synthesize an enter event. - */ - if (event != &canvas->pick_event) { - if ((event->type == GDK_MOTION_NOTIFY) || (event->type == GDK_BUTTON_RELEASE)) { - /* these fields have the same offsets in both types of events */ - - canvas->pick_event.crossing.type = GDK_ENTER_NOTIFY; - canvas->pick_event.crossing.window = event->motion.window; - canvas->pick_event.crossing.send_event = event->motion.send_event; - canvas->pick_event.crossing.subwindow = NULL; - canvas->pick_event.crossing.x = event->motion.x; - canvas->pick_event.crossing.y = event->motion.y; - canvas->pick_event.crossing.mode = GDK_CROSSING_NORMAL; - canvas->pick_event.crossing.detail = GDK_NOTIFY_NONLINEAR; - canvas->pick_event.crossing.focus = FALSE; - canvas->pick_event.crossing.state = event->motion.state; - - /* these fields don't have the same offsets in both types of events */ - - if (event->type == GDK_MOTION_NOTIFY) { - canvas->pick_event.crossing.x_root = event->motion.x_root; - canvas->pick_event.crossing.y_root = event->motion.y_root; - } else { - canvas->pick_event.crossing.x_root = event->button.x_root; - canvas->pick_event.crossing.y_root = event->button.y_root; - } - } else - canvas->pick_event = *event; - } - - /* Don't do anything else if this is a recursive call */ - - if (canvas->in_repick) - return retval; - - /* LeaveNotify means that there is no current item, so we don't look for one */ - - if (canvas->pick_event.type != GDK_LEAVE_NOTIFY) { - /* these fields don't have the same offsets in both types of events */ - - if (canvas->pick_event.type == GDK_ENTER_NOTIFY) { - x = canvas->pick_event.crossing.x; - y = canvas->pick_event.crossing.y; - } else { - x = canvas->pick_event.motion.x; - y = canvas->pick_event.motion.y; - } - - /* canvas pixel coords */ - - cx = (int) (x + 0.5); - cy = (int) (y + 0.5); - - /* world coords */ - foo_canvas_c2w (canvas, cx, cy, &x, &y); - - /* find the closest item */ - if (canvas->root->object.flags & FOO_CANVAS_ITEM_MAPPED) - foo_canvas_item_invoke_point (canvas->root, x, y, cx, cy, - &canvas->new_current_item); - else - canvas->new_current_item = NULL; - } else - canvas->new_current_item = NULL; - - if ((canvas->new_current_item == canvas->current_item) && !canvas->left_grabbed_item) - return retval; /* current item did not change */ - - /* Synthesize events for old and new current items */ - - if ((canvas->new_current_item != canvas->current_item) - && (canvas->current_item != NULL) - && !canvas->left_grabbed_item) { - GdkEvent new_event; - FooCanvasItem *item; - - item = canvas->current_item; - - new_event = canvas->pick_event; - new_event.type = GDK_LEAVE_NOTIFY; - - new_event.crossing.detail = GDK_NOTIFY_ANCESTOR; - new_event.crossing.subwindow = NULL; - canvas->in_repick = TRUE; - retval = emit_event (canvas, &new_event); - canvas->in_repick = FALSE; - } - - /* new_current_item may have been set to NULL during the call to emit_event() above */ - - if ((canvas->new_current_item != canvas->current_item) && button_down) { - canvas->left_grabbed_item = TRUE; - return retval; - } - - /* Handle the rest of cases */ - - canvas->left_grabbed_item = FALSE; - canvas->current_item = canvas->new_current_item; - - if (canvas->current_item != NULL) { - GdkEvent new_event; - - new_event = canvas->pick_event; - new_event.type = GDK_ENTER_NOTIFY; - new_event.crossing.detail = GDK_NOTIFY_ANCESTOR; - new_event.crossing.subwindow = NULL; - retval = emit_event (canvas, &new_event); - } - - return retval; -} - -/* Button event handler for the canvas */ -static gint -foo_canvas_button (GtkWidget *widget, GdkEventButton *event) -{ - FooCanvas *canvas; - int mask; - int retval; - - g_return_val_if_fail (FOO_IS_CANVAS (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - retval = FALSE; - - canvas = FOO_CANVAS (widget); - - /* - * dispatch normally regardless of the event's window if an item has - * has a pointer grab in effect - */ - if (!canvas->grabbed_item && event->window != canvas->layout.bin_window) - return retval; - - switch (event->button) { - case 1: - mask = GDK_BUTTON1_MASK; - break; - case 2: - mask = GDK_BUTTON2_MASK; - break; - case 3: - mask = GDK_BUTTON3_MASK; - break; - case 4: - mask = GDK_BUTTON4_MASK; - break; - case 5: - mask = GDK_BUTTON5_MASK; - break; - default: - mask = 0; - } - - switch (event->type) { - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - /* Pick the current item as if the button were not pressed, and - * then process the event. - */ - canvas->state = event->state; - pick_current_item (canvas, (GdkEvent *) event); - canvas->state ^= mask; - retval = emit_event (canvas, (GdkEvent *) event); - break; - - case GDK_BUTTON_RELEASE: - /* Process the event as if the button were pressed, then repick - * after the button has been released - */ - canvas->state = event->state; - retval = emit_event (canvas, (GdkEvent *) event); - event->state ^= mask; - canvas->state = event->state; - pick_current_item (canvas, (GdkEvent *) event); - event->state ^= mask; - break; - - default: - g_assert_not_reached (); - } - - return retval; -} - -/* Motion event handler for the canvas */ -static gint -foo_canvas_motion (GtkWidget *widget, GdkEventMotion *event) -{ - FooCanvas *canvas; - - g_return_val_if_fail (FOO_IS_CANVAS (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - canvas = FOO_CANVAS (widget); - - if (event->window != canvas->layout.bin_window) - return FALSE; - - canvas->state = event->state; - pick_current_item (canvas, (GdkEvent *) event); - return emit_event (canvas, (GdkEvent *) event); -} - -/* Key event handler for the canvas */ -static gint -foo_canvas_key (GtkWidget *widget, GdkEventKey *event) -{ - FooCanvas *canvas; - - g_return_val_if_fail (FOO_IS_CANVAS (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - canvas = FOO_CANVAS (widget); - - if (emit_event (canvas, (GdkEvent *) event)) - return TRUE; - if (event->type == GDK_KEY_RELEASE) - return GTK_WIDGET_CLASS (canvas_parent_class)->key_release_event (widget, event); - else - return GTK_WIDGET_CLASS (canvas_parent_class)->key_press_event (widget, event); -} - - -/* Crossing event handler for the canvas */ -static gint -foo_canvas_crossing (GtkWidget *widget, GdkEventCrossing *event) -{ - FooCanvas *canvas; - - g_return_val_if_fail (FOO_IS_CANVAS (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - canvas = FOO_CANVAS (widget); - - if (event->window != canvas->layout.bin_window) - return FALSE; - - canvas->state = event->state; - return pick_current_item (canvas, (GdkEvent *) event); -} - -/* Focus in handler for the canvas */ -static gint -foo_canvas_focus_in (GtkWidget *widget, GdkEventFocus *event) -{ - FooCanvas *canvas; - - GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); - - canvas = FOO_CANVAS (widget); - - if (canvas->focused_item) - return emit_event (canvas, (GdkEvent *) event); - else - return FALSE; -} - -/* Focus out handler for the canvas */ -static gint -foo_canvas_focus_out (GtkWidget *widget, GdkEventFocus *event) -{ - FooCanvas *canvas; - - GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); - - canvas = FOO_CANVAS (widget); - - if (canvas->focused_item) - return emit_event (canvas, (GdkEvent *) event); - else - return FALSE; -} - -/* Expose handler for the canvas */ -static gint -foo_canvas_expose (GtkWidget *widget, GdkEventExpose *event) -{ - FooCanvas *canvas; - - canvas = FOO_CANVAS (widget); - - if (!GTK_WIDGET_DRAWABLE (widget) || (event->window != canvas->layout.bin_window)) return FALSE; - -#ifdef VERBOSE - g_print ("Expose\n"); -#endif - /* If there are any outstanding items that need updating, do them now */ - if (canvas->idle_id) { - g_source_remove (canvas->idle_id); - canvas->idle_id = 0; - } - if (canvas->need_update) { - g_return_val_if_fail (!canvas->doing_update, FALSE); - - canvas->doing_update = TRUE; - foo_canvas_item_invoke_update (canvas->root, 0, 0, 0); - - g_return_val_if_fail (canvas->doing_update, FALSE); - - canvas->doing_update = FALSE; - - canvas->need_update = FALSE; - } - - /* Hmmm. Would like to queue antiexposes if the update marked - anything that is gonna get redrawn as invalid */ - - - g_signal_emit (G_OBJECT (canvas), canvas_signals[DRAW_BACKGROUND], 0, - event->area.x, event->area.y, - event->area.width, event->area.height); - - if (canvas->root->object.flags & FOO_CANVAS_ITEM_MAPPED) - (* FOO_CANVAS_ITEM_GET_CLASS (canvas->root)->draw) (canvas->root, - canvas->layout.bin_window, - event); - - - - /* Chain up to get exposes on child widgets */ - GTK_WIDGET_CLASS (canvas_parent_class)->expose_event (widget, event); - - return FALSE; -} - -static void -foo_canvas_draw_background (FooCanvas *canvas, - int x, int y, int width, int height) -{ - /* By default, we use the style background. */ - gdk_gc_set_foreground (canvas->pixmap_gc, - >K_WIDGET (canvas)->style->bg[GTK_STATE_NORMAL]); - gdk_draw_rectangle (canvas->layout.bin_window, - canvas->pixmap_gc, - TRUE, - x, y, - width, height); -} - -static void -do_update (FooCanvas *canvas) -{ - /* Cause the update if necessary */ - -update_again: - if (canvas->need_update) { - g_return_if_fail (!canvas->doing_update); - - canvas->doing_update = TRUE; - foo_canvas_item_invoke_update (canvas->root, 0, 0, 0); - - g_return_if_fail (canvas->doing_update); - - canvas->doing_update = FALSE; - - canvas->need_update = FALSE; - } - - /* Pick new current item */ - - while (canvas->need_repick) { - canvas->need_repick = FALSE; - pick_current_item (canvas, &canvas->pick_event); - } - - /* it is possible that during picking we emitted an event in which - the user then called some function which then requested update - of something. Without this we'd be left in a state where - need_update would have been left TRUE and the canvas would have - been left unpainted. */ - if (canvas->need_update) { - goto update_again; - } -} - -/* Idle handler for the canvas. It deals with pending updates and redraws. */ -static gint -idle_handler (gpointer data) -{ - FooCanvas *canvas; - - GDK_THREADS_ENTER (); - - canvas = FOO_CANVAS (data); - do_update (canvas); - - /* Reset idle id */ - canvas->idle_id = 0; - - GDK_THREADS_LEAVE (); - - return FALSE; -} - -/* Convenience function to add an idle handler to a canvas */ -static void -add_idle (FooCanvas *canvas) -{ - if (!canvas->idle_id) { - /* We let the update idle handler have higher priority - * than the redraw idle handler so the canvas state - * will be updated during the expose event. canvas in - * expose_event. - */ - canvas->idle_id = g_idle_add_full (GDK_PRIORITY_REDRAW - 20, - idle_handler, canvas, NULL); - } -} - -/** - * foo_canvas_root: - * @canvas: A canvas. - * - * Queries the root group of a canvas. - * - * Return value: The root group of the specified canvas. - **/ -FooCanvasGroup * -foo_canvas_root (FooCanvas *canvas) -{ - g_return_val_if_fail (FOO_IS_CANVAS (canvas), NULL); - - return FOO_CANVAS_GROUP (canvas->root); -} - - -/** - * foo_canvas_set_scroll_region: - * @canvas: A canvas. - * @x1: Leftmost limit of the scrolling region. - * @y1: Upper limit of the scrolling region. - * @x2: Rightmost limit of the scrolling region. - * @y2: Lower limit of the scrolling region. - * - * Sets the scrolling region of a canvas to the specified rectangle. The canvas - * will then be able to scroll only within this region. The view of the canvas - * is adjusted as appropriate to display as much of the new region as possible. - **/ -void -foo_canvas_set_scroll_region (FooCanvas *canvas, double x1, double y1, double x2, double y2) -{ - double wxofs, wyofs; - int xofs, yofs; - - g_return_if_fail (FOO_IS_CANVAS (canvas)); - - if ((canvas->scroll_x1 == x1) && (canvas->scroll_y1 == y1) && - (canvas->scroll_x2 == x2) && (canvas->scroll_y2 == y2)) { - return; - } - - /* - * Set the new scrolling region. If possible, do not move the visible contents of the - * canvas. - */ - - foo_canvas_c2w (canvas, - GTK_LAYOUT (canvas)->hadjustment->value + canvas->zoom_xofs, - GTK_LAYOUT (canvas)->vadjustment->value + canvas->zoom_yofs, - /*canvas->zoom_xofs, - canvas->zoom_yofs,*/ - &wxofs, &wyofs); - - canvas->scroll_x1 = x1; - canvas->scroll_y1 = y1; - canvas->scroll_x2 = x2; - canvas->scroll_y2 = y2; - - foo_canvas_w2c (canvas, wxofs, wyofs, &xofs, &yofs); - - scroll_to (canvas, xofs, yofs); - - canvas->need_repick = TRUE; - - if (!(canvas->root->object.flags & FOO_CANVAS_ITEM_NEED_DEEP_UPDATE)) { - canvas->root->object.flags |= FOO_CANVAS_ITEM_NEED_DEEP_UPDATE; - foo_canvas_request_update (canvas); - } -} - - -/** - * foo_canvas_get_scroll_region: - * @canvas: A canvas. - * @x1: Leftmost limit of the scrolling region (return value). - * @y1: Upper limit of the scrolling region (return value). - * @x2: Rightmost limit of the scrolling region (return value). - * @y2: Lower limit of the scrolling region (return value). - * - * Queries the scrolling region of a canvas. - **/ -void -foo_canvas_get_scroll_region (FooCanvas *canvas, double *x1, double *y1, double *x2, double *y2) -{ - g_return_if_fail (FOO_IS_CANVAS (canvas)); - - if (x1) - *x1 = canvas->scroll_x1; - - if (y1) - *y1 = canvas->scroll_y1; - - if (x2) - *x2 = canvas->scroll_x2; - - if (y2) - *y2 = canvas->scroll_y2; -} - -void -foo_canvas_set_center_scroll_region (FooCanvas *canvas, - gboolean center_scroll_region) -{ - g_return_if_fail (FOO_IS_CANVAS (canvas)); - - canvas->center_scroll_region = center_scroll_region != 0; - - scroll_to (canvas, - canvas->layout.hadjustment->value, - canvas->layout.vadjustment->value); -} - - -/** - * foo_canvas_set_pixels_per_unit: - * @canvas: A canvas - * @n: The number of pixels that correspond to one canvas unit. - * - * Sets the zooming factor of a canvas by specifying the number of pixels that - * correspond to one canvas unit. - * This is retained for backwards compatibility and just calls - * foo_canvas_set_pixels_per_unit_xy, passing the number of pixels/unit twice. - **/ -void -foo_canvas_set_pixels_per_unit (FooCanvas *canvas, double n) -{ - foo_canvas_set_pixels_per_unit_xy(canvas, n, n); - return; -} - - -/** - * foo_canvas_set_pixels_per_unit_xy: - * @canvas: A canvas. - * @x: The number of pixels that correspond to one canvas unit on the x axis. - * @y: The number of pixels that correspond to one canvas unit on the y axis. - * - * Sets the zooming factor of a canvas by specifying the number of pixels that - * correspond to one canvas unit. - * Having two zooming factors enables asymmetric zooming. - **/ -void -foo_canvas_set_pixels_per_unit_xy (FooCanvas *canvas, double x, double y) -{ - GtkWidget *widget; - double cx, cy; - int x1, y1; - int center_x, center_y; - GdkWindow *window; - GdkWindowAttr attributes; - gint attributes_mask; - - g_return_if_fail (FOO_IS_CANVAS (canvas)); - /* guessing that the x factor is OK here. RNCG */ - g_return_if_fail (x > FOO_CANVAS_EPSILON); - - widget = GTK_WIDGET (canvas); - - center_x = widget->allocation.width / 2; - center_y = widget->allocation.height / 2; - - /* Find the coordinates of the screen center in units. */ - cx = (canvas->layout.hadjustment->value + center_x) / canvas->pixels_per_unit_x + canvas->scroll_x1 + canvas->zoom_xofs; - cy = (canvas->layout.vadjustment->value + center_y) / canvas->pixels_per_unit_y + canvas->scroll_y1 + canvas->zoom_yofs; - - /* Now calculate the new offset of the upper left corner. (round not truncate) */ - x1 = ((cx - canvas->scroll_x1) * x) - center_x + .5; - y1 = ((cy - canvas->scroll_y1) * y) - center_y + .5; - - canvas->pixels_per_unit_x = x; - canvas->pixels_per_unit_y = y; - - if (!(canvas->root->object.flags & FOO_CANVAS_ITEM_NEED_DEEP_UPDATE)) { - canvas->root->object.flags |= FOO_CANVAS_ITEM_NEED_DEEP_UPDATE; - foo_canvas_request_update (canvas); - } - - /* Map a background None window over the bin_window to avoid - * scrolling the window scroll causing exposes. - */ - window = NULL; - if (GTK_WIDGET_MAPPED (widget)) { - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = widget->allocation.x; - attributes.y = widget->allocation.y; - attributes.width = widget->allocation.width; - attributes.height = widget->allocation.height; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK; - - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - - window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gdk_window_set_back_pixmap (window, NULL, FALSE); - gdk_window_set_user_data (window, widget); - - gdk_window_show (window); - } - - scroll_to (canvas, x1, y1); - - /* If we created a an overlapping background None window, remove it how. - * - * TODO: We would like to temporarily set the bin_window background to - * None to avoid clearing the bin_window to the background, but gdk doesn't - * expose enought to let us do this, so we get a flash-effect here. At least - * it looks better than scroll + expose. - */ - if (window != NULL) { - gdk_window_hide (window); - gdk_window_set_user_data (window, NULL); - gdk_window_destroy (window); - } - - canvas->need_repick = TRUE; -} - -/** - * foo_canvas_scroll_to: - * @canvas: A canvas. - * @cx: Horizontal scrolling offset in canvas pixel units. - * @cy: Vertical scrolling offset in canvas pixel units. - * - * Makes a canvas scroll to the specified offsets, given in canvas pixel units. - * The canvas will adjust the view so that it is not outside the scrolling - * region. This function is typically not used, as it is better to hook - * scrollbars to the canvas layout's scrolling adjusments. - **/ -void -foo_canvas_scroll_to (FooCanvas *canvas, int cx, int cy) -{ - g_return_if_fail (FOO_IS_CANVAS (canvas)); - - scroll_to (canvas, cx, cy); -} - -/** - * foo_canvas_get_scroll_offsets: - * @canvas: A canvas. - * @cx: Horizontal scrolling offset (return value). - * @cy: Vertical scrolling offset (return value). - * - * Queries the scrolling offsets of a canvas. The values are returned in canvas - * pixel units. - **/ -void -foo_canvas_get_scroll_offsets (FooCanvas *canvas, int *cx, int *cy) -{ - g_return_if_fail (FOO_IS_CANVAS (canvas)); - - if (cx) - *cx = canvas->layout.hadjustment->value; - - if (cy) - *cy = canvas->layout.vadjustment->value; -} - -/** - * foo_canvas_update_now: - * @canvas: A canvas. - * - * Forces an immediate update and redraw of a canvas. If the canvas does not - * have any pending update or redraw requests, then no action is taken. This is - * typically only used by applications that need explicit control of when the - * display is updated, like games. It is not needed by normal applications. - */ -void -foo_canvas_update_now (FooCanvas *canvas) -{ - g_return_if_fail (FOO_IS_CANVAS (canvas)); - - if (!(canvas->need_update || canvas->need_redraw)) - return; - remove_idle (canvas); - do_update (canvas); -} - -/** - * foo_canvas_get_item_at: - * @canvas: A canvas. - * @x: X position in world coordinates. - * @y: Y position in world coordinates. - * - * Looks for the item that is under the specified position, which must be - * specified in world coordinates. - * - * Return value: The sought item, or NULL if no item is at the specified - * coordinates. - **/ -FooCanvasItem * -foo_canvas_get_item_at (FooCanvas *canvas, double x, double y) -{ - FooCanvasItem *item; - double dist; - int cx, cy; - - g_return_val_if_fail (FOO_IS_CANVAS (canvas), NULL); - - foo_canvas_w2c (canvas, x, y, &cx, &cy); - - dist = foo_canvas_item_invoke_point (canvas->root, x, y, cx, cy, &item); - /* guessing the x factor is OK here. RNGC */ - if ((int) (dist * canvas->pixels_per_unit_x + 0.5) <= canvas->close_enough) - return item; - else - return NULL; -} - -/* Queues an update of the canvas */ -static void -foo_canvas_request_update (FooCanvas *canvas) -{ - FOO_CANVAS_GET_CLASS (canvas)->request_update (canvas); -} - -static void -foo_canvas_request_update_real (FooCanvas *canvas) -{ - canvas->need_update = TRUE; - add_idle (canvas); -} - -/** - * foo_canvas_request_redraw: - * @canvas: A canvas. - * @x1: Leftmost coordinate of the rectangle to be redrawn. - * @y1: Upper coordinate of the rectangle to be redrawn. - * @x2: Rightmost coordinate of the rectangle to be redrawn, plus 1. - * @y2: Lower coordinate of the rectangle to be redrawn, plus 1. - * - * Convenience function that informs a canvas that the specified rectangle needs - * to be repainted. The rectangle includes @x1 and @y1, but not @x2 and @y2. - * To be used only by item implementations. - **/ -void -foo_canvas_request_redraw (FooCanvas *canvas, int x1, int y1, int x2, int y2) -{ - GdkRectangle bbox; - - g_return_if_fail (FOO_IS_CANVAS (canvas)); - - if (!GTK_WIDGET_DRAWABLE (canvas) || (x1 >= x2) || (y1 >= y2)) return; - - bbox.x = x1; - bbox.y = y1; - bbox.width = x2 - x1; - bbox.height = y2 - y1; - - gdk_window_invalidate_rect (canvas->layout.bin_window, - &bbox, FALSE); -} - -/** - * foo_canvas_w2c: - * @canvas: A canvas. - * @wx: World X coordinate. - * @wy: World Y coordinate. - * @cx: X pixel coordinate (return value). - * @cy: Y pixel coordinate (return value). - * - * Converts world coordinates into canvas pixel coordinates. - **/ -void -foo_canvas_w2c (FooCanvas *canvas, double wx, double wy, int *cx, int *cy) -{ - double zoom_x, zoom_y; - - g_return_if_fail (FOO_IS_CANVAS (canvas)); - - zoom_x = canvas->pixels_per_unit_x; - zoom_y = canvas->pixels_per_unit_y; - - if (cx) - *cx = floor ((wx - canvas->scroll_x1)*zoom_x + canvas->zoom_xofs + 0.5); - if (cy) - *cy = floor ((wy - canvas->scroll_y1)*zoom_y + canvas->zoom_yofs + 0.5); -} - -/** - * foo_canvas_w2c: - * @canvas: A canvas. - * @world: rectangle in world coordinates. - * @canvas: rectangle in canvase coordinates. - * - * Converts rectangles in world coordinates into canvas pixel coordinates. - **/ -void -foo_canvas_w2c_rect_d (FooCanvas *canvas, - double *x1, double *y1, - double *x2, double *y2) -{ - foo_canvas_w2c_d (canvas, - *x1, *y1, - x1, y1); - foo_canvas_w2c_d (canvas, - *x2, *y2, - x2, y2); -} - - - -/** - * foo_canvas_w2c_d: - * @canvas: A canvas. - * @wx: World X coordinate. - * @wy: World Y coordinate. - * @cx: X pixel coordinate (return value). - * @cy: Y pixel coordinate (return value). - * - * Converts world coordinates into canvas pixel coordinates. This version - * returns coordinates in floating point coordinates, for greater precision. - **/ -void -foo_canvas_w2c_d (FooCanvas *canvas, double wx, double wy, double *cx, double *cy) -{ - double zoom_x, zoom_y; - - g_return_if_fail (FOO_IS_CANVAS (canvas)); - - zoom_x = canvas->pixels_per_unit_x; - zoom_y = canvas->pixels_per_unit_y; - - if (cx) - *cx = (wx - canvas->scroll_x1)*zoom_x + canvas->zoom_xofs; - if (cy) - *cy = (wy - canvas->scroll_y1)*zoom_y + canvas->zoom_yofs; -} - - -/** - * foo_canvas_c2w: - * @canvas: A canvas. - * @cx: Canvas pixel X coordinate. - * @cy: Canvas pixel Y coordinate. - * @wx: X world coordinate (return value). - * @wy: Y world coordinate (return value). - * - * Converts canvas pixel coordinates to world coordinates. - **/ -void -foo_canvas_c2w (FooCanvas *canvas, int cx, int cy, double *wx, double *wy) -{ - double zoom_x, zoom_y; - - g_return_if_fail (FOO_IS_CANVAS (canvas)); - - zoom_x = canvas->pixels_per_unit_x; - zoom_y = canvas->pixels_per_unit_y; - - if (wx) - *wx = (cx - canvas->zoom_xofs)/zoom_x + canvas->scroll_x1; - if (wy) - *wy = (cy - canvas->zoom_yofs)/zoom_y + canvas->scroll_y1; -} - - -/** - * foo_canvas_window_to_world: - * @canvas: A canvas. - * @winx: Window-relative X coordinate. - * @winy: Window-relative Y coordinate. - * @worldx: X world coordinate (return value). - * @worldy: Y world coordinate (return value). - * - * Converts window-relative coordinates into world coordinates. You can use - * this when you need to convert mouse coordinates into world coordinates, for - * example. - * Window coordinates are really the same as canvas coordinates now, but this - * function is here for backwards compatibility reasons. - **/ -void -foo_canvas_window_to_world (FooCanvas *canvas, double winx, double winy, - double *worldx, double *worldy) -{ - g_return_if_fail (FOO_IS_CANVAS (canvas)); - - if (worldx) - *worldx = canvas->scroll_x1 + ((winx - canvas->zoom_xofs) - / canvas->pixels_per_unit_x); - - if (worldy) - *worldy = canvas->scroll_y1 + ((winy - canvas->zoom_yofs) - / canvas->pixels_per_unit_y); -} - - -/** - * foo_canvas_world_to_window: - * @canvas: A canvas. - * @worldx: World X coordinate. - * @worldy: World Y coordinate. - * @winx: X window-relative coordinate. - * @winy: Y window-relative coordinate. - * - * Converts world coordinates into window-relative coordinates. - * Window coordinates are really the same as canvas coordinates now, but this - * function is here for backwards compatibility reasons. - **/ -void -foo_canvas_world_to_window (FooCanvas *canvas, double worldx, double worldy, - double *winx, double *winy) -{ - g_return_if_fail (FOO_IS_CANVAS (canvas)); - - if (winx) - *winx = (canvas->pixels_per_unit_x)*(worldx - canvas->scroll_x1) + canvas->zoom_xofs; - - if (winy) - *winy = (canvas->pixels_per_unit_y)*(worldy - canvas->scroll_y1) + canvas->zoom_yofs; -} - - - -/** - * foo_canvas_get_color: - * @canvas: A canvas. - * @spec: X color specification, or NULL for "transparent". - * @color: Returns the allocated color. - * - * Allocates a color based on the specified X color specification. As a - * convenience to item implementations, it returns TRUE if the color was - * allocated, or FALSE if the specification was NULL. A NULL color - * specification is considered as "transparent" by the canvas. - * - * Return value: TRUE if @spec is non-NULL and the color is allocated. If @spec - * is NULL, then returns FALSE. - **/ -int -foo_canvas_get_color (FooCanvas *canvas, const char *spec, GdkColor *color) -{ - GdkColormap *colormap; - - g_return_val_if_fail (FOO_IS_CANVAS (canvas), FALSE); - g_return_val_if_fail (color != NULL, FALSE); - - if (!spec) { - color->pixel = 0; - color->red = 0; - color->green = 0; - color->blue = 0; - return FALSE; - } - - gdk_color_parse (spec, color); - - colormap = gtk_widget_get_colormap (GTK_WIDGET (canvas)); - - gdk_rgb_find_color (colormap, color); - - return TRUE; -} - -/** - * foo_canvas_get_color_pixel: - * @canvas: A canvas. - * @rgba: RGBA color specification. - * - * Allocates a color from the RGBA value passed into this function. The alpha - * opacity value is discarded, since normal X colors do not support it. - * - * Return value: Allocated pixel value corresponding to the specified color. - **/ -gulong -foo_canvas_get_color_pixel (FooCanvas *canvas, guint rgba) -{ - GdkColormap *colormap; - GdkColor color; - - g_return_val_if_fail (FOO_IS_CANVAS (canvas), 0); - - color.red = ((rgba & 0xff000000) >> 16) + ((rgba & 0xff000000) >> 24); - color.green = ((rgba & 0x00ff0000) >> 8) + ((rgba & 0x00ff0000) >> 16); - color.blue = (rgba & 0x0000ff00) + ((rgba & 0x0000ff00) >> 8); - color.pixel = 0; - - colormap = gtk_widget_get_colormap (GTK_WIDGET (canvas)); - - gdk_rgb_find_color (colormap, &color); - - return color.pixel; -} - - -/* FIXME: This function is not useful anymore */ -/** - * foo_canvas_set_stipple_origin: - * @canvas: A canvas. - * @gc: GC on which to set the stipple origin. - * - * Sets the stipple origin of the specified GC as is appropriate for the canvas, - * so that it will be aligned with other stipple patterns used by canvas items. - * This is typically only needed by item implementations. - **/ -void -foo_canvas_set_stipple_origin (FooCanvas *canvas, GdkGC *gc) -{ - g_return_if_fail (FOO_IS_CANVAS (canvas)); - g_return_if_fail (GDK_IS_GC (gc)); - - gdk_gc_set_ts_origin (gc, 0, 0); -} - -static gboolean -boolean_handled_accumulator (GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, - gpointer dummy) -{ - gboolean continue_emission; - gboolean signal_handled; - - signal_handled = g_value_get_boolean (handler_return); - g_value_set_boolean (return_accu, signal_handled); - continue_emission = !signal_handled; - - return continue_emission; -} - -static guint -foo_canvas_item_accessible_add_focus_handler (AtkComponent *component, - AtkFocusHandler handler) -{ - GSignalMatchType match_type; - guint signal_id; - - match_type = G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC; - signal_id = g_signal_lookup ("focus-event", ATK_TYPE_OBJECT); - - if (!g_signal_handler_find (component, match_type, signal_id, 0, NULL, - (gpointer) handler, NULL)) { - return g_signal_connect_closure_by_id (component, - signal_id, 0, - g_cclosure_new ( - G_CALLBACK (handler), NULL, - (GClosureNotify) NULL), - FALSE); - } - return 0; -} - -static void -foo_canvas_item_accessible_get_item_extents (FooCanvasItem *item, - GdkRectangle *rect) -{ - double bx1, bx2, by1, by2; - gint scroll_x, scroll_y; - gint x1, x2, y1, y2; - - foo_canvas_item_get_bounds (item, &bx1, &by1, &bx2, &by2); - foo_canvas_w2c_rect_d (item->canvas, &bx1, &by1, &bx2, &by2); - foo_canvas_get_scroll_offsets (item->canvas, &scroll_x, &scroll_y); - x1 = floor (bx1); - y1 = floor (by1); - x2 = ceil (bx2); - y2 = ceil (by2); - rect->x = x1 - scroll_x; - rect->y = y1 - scroll_y; - rect->width = x2 - x1; - rect->height = y2 - y1; -} - -static gboolean -foo_canvas_item_accessible_is_item_in_window (FooCanvasItem *item, - GdkRectangle *rect) -{ - GtkWidget *widget; - gboolean retval; - - widget = GTK_WIDGET (item->canvas); - if (widget->window) { - int window_width, window_height; - - gdk_window_get_geometry (widget->window, NULL, NULL, - &window_width, &window_height, NULL); - /* - * Check whether rectangles intersect - */ - if (rect->x + rect->width < 0 || - rect->y + rect->height < 0 || - rect->x > window_width || - rect->y > window_height) { - retval = FALSE; - } else { - retval = TRUE; - } - } else { - retval = FALSE; - } - return retval; -} - - -static void -foo_canvas_item_accessible_get_extents (AtkComponent *component, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coord_type) -{ - AtkGObjectAccessible *atk_gobj; - GObject *obj; - FooCanvasItem *item; - gint window_x, window_y; - gint toplevel_x, toplevel_y; - GdkRectangle rect; - GdkWindow *window; - GtkWidget *canvas; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (component); - obj = atk_gobject_accessible_get_object (atk_gobj); - - if (obj == NULL) { - /* item is defunct */ - return; - } - - /* Get the CanvasItem */ - item = FOO_CANVAS_ITEM (obj); - - /* If this item has no parent canvas, something's broken */ - g_return_if_fail (GTK_IS_WIDGET (item->canvas)); - - foo_canvas_item_accessible_get_item_extents (item, &rect); - *width = rect.width; - *height = rect.height; - if (!foo_canvas_item_accessible_is_item_in_window (item, &rect)) { - *x = G_MININT; - *y = G_MININT; - return; - } - - canvas = GTK_WIDGET (item->canvas); - window = gtk_widget_get_parent_window (canvas); - gdk_window_get_origin (window, &window_x, &window_y); - *x = rect.x + window_x; - *y = rect.y + window_y; - if (coord_type == ATK_XY_WINDOW) { - window = gdk_window_get_toplevel (canvas->window); - gdk_window_get_origin (window, &toplevel_x, &toplevel_y); - *x -= toplevel_x; - *y -= toplevel_y; - } - return; -} - -static gint -foo_canvas_item_accessible_get_mdi_zorder (AtkComponent *component) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - FooCanvasItem *item; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (component); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (g_obj == NULL) { - /* Object is defunct */ - return -1; - } - - item = FOO_CANVAS_ITEM (g_obj); - if (item->parent) { - return g_list_index (FOO_CANVAS_GROUP (item->parent)->item_list, item); - } else { - g_return_val_if_fail (item->canvas->root == item, -1); - return 0; - } -} - -static gboolean -foo_canvas_item_accessible_grab_focus (AtkComponent *component) -{ - AtkGObjectAccessible *atk_gobj; - GObject *obj; - FooCanvasItem *item; - GtkWidget *toplevel; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (component); - obj = atk_gobject_accessible_get_object (atk_gobj); - - item = FOO_CANVAS_ITEM (obj); - if (item == NULL) { - /* item is defunct */ - return FALSE; - } - - foo_canvas_item_grab_focus (item); - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item->canvas)); - if (GTK_WIDGET_TOPLEVEL (toplevel)) { - gtk_window_present (GTK_WINDOW (toplevel)); - } - - return TRUE; -} - -static void -foo_canvas_item_accessible_remove_focus_handler (AtkComponent *component, - guint handler_id) -{ - g_signal_handler_disconnect (component, handler_id); -} - -static void -foo_canvas_item_accessible_component_interface_init (AtkComponentIface *iface) -{ - g_return_if_fail (iface != NULL); - - iface->add_focus_handler = foo_canvas_item_accessible_add_focus_handler; - iface->get_extents = foo_canvas_item_accessible_get_extents; - iface->get_mdi_zorder = foo_canvas_item_accessible_get_mdi_zorder; - iface->grab_focus = foo_canvas_item_accessible_grab_focus; - iface->remove_focus_handler = foo_canvas_item_accessible_remove_focus_handler; -} - -static gboolean -foo_canvas_item_accessible_is_item_on_screen (FooCanvasItem *item) -{ - GdkRectangle rect; - - foo_canvas_item_accessible_get_item_extents (item, &rect); - return foo_canvas_item_accessible_is_item_in_window (item, &rect); -} - -static void -foo_canvas_item_accessible_initialize (AtkObject *obj, gpointer data) -{ - if (ATK_OBJECT_CLASS (accessible_item_parent_class)->initialize != NULL) - ATK_OBJECT_CLASS (accessible_item_parent_class)->initialize (obj, data); - g_object_set_data (G_OBJECT (obj), "atk-component-layer", - GINT_TO_POINTER (ATK_LAYER_MDI)); -} - -static AtkStateSet* -foo_canvas_item_accessible_ref_state_set (AtkObject *accessible) -{ - AtkGObjectAccessible *atk_gobj; - GObject *obj; - FooCanvasItem *item; - AtkStateSet *state_set; - - state_set = ATK_OBJECT_CLASS (accessible_item_parent_class)->ref_state_set (accessible); - atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); - obj = atk_gobject_accessible_get_object (atk_gobj); - - item = FOO_CANVAS_ITEM (obj); - if (item == NULL) { - atk_state_set_add_state (state_set, ATK_STATE_DEFUNCT); - } else { - if (item->object.flags & FOO_CANVAS_ITEM_VISIBLE) { - atk_state_set_add_state (state_set, ATK_STATE_VISIBLE); - - if (foo_canvas_item_accessible_is_item_on_screen (item)) { - atk_state_set_add_state (state_set, ATK_STATE_SHOWING); - } - } - if (GTK_WIDGET_CAN_FOCUS (GTK_WIDGET (item->canvas))) { - atk_state_set_add_state (state_set, ATK_STATE_FOCUSABLE); - - if (item->canvas->focused_item == item) { - atk_state_set_add_state (state_set, ATK_STATE_FOCUSED); - } - } - } - - return state_set; -} - -static void -foo_canvas_item_accessible_class_init (AtkObjectClass *klass) -{ - accessible_item_parent_class = g_type_class_peek_parent (klass); - - klass->initialize = foo_canvas_item_accessible_initialize; - klass->ref_state_set = foo_canvas_item_accessible_ref_state_set; -} - -static GType -foo_canvas_item_accessible_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GInterfaceInfo atk_component_info = { - (GInterfaceInitFunc) foo_canvas_item_accessible_component_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - AtkObjectFactory *factory; - GType parent_atk_type; - GTypeQuery query; - GTypeInfo tinfo = { 0 }; - - factory = atk_registry_get_factory (atk_get_default_registry(), - GTK_TYPE_OBJECT); - if (!factory) { - return G_TYPE_INVALID; - } - parent_atk_type = atk_object_factory_get_accessible_type (factory); - if (!parent_atk_type) { - return G_TYPE_INVALID; - } - g_type_query (parent_atk_type, &query); - tinfo.class_init = (GClassInitFunc) foo_canvas_item_accessible_class_init; - tinfo.class_size = query.class_size; - tinfo.instance_size = query.instance_size; - type = g_type_register_static (parent_atk_type, - "FooCanvasItemAccessibility", - &tinfo, 0); - - g_type_add_interface_static (type, ATK_TYPE_COMPONENT, - &atk_component_info); - - } - - return type; -} - -static AtkObject * -foo_canvas_item_accessible_create (GObject *for_object) -{ - GType type; - AtkObject *accessible; - FooCanvasItem *item; - - item = FOO_CANVAS_ITEM (for_object); - g_return_val_if_fail (item != NULL, NULL); - - type = foo_canvas_item_accessible_get_type (); - if (type == G_TYPE_INVALID) { - return atk_no_op_object_new (for_object); - } - - accessible = g_object_new (type, NULL); - atk_object_initialize (accessible, for_object); - return accessible; -} - -static GType -foo_canvas_item_accessible_factory_get_accessible_type (void) -{ - return foo_canvas_item_accessible_get_type (); -} - -static AtkObject* -foo_canvas_item_accessible_factory_create_accessible (GObject *obj) -{ - AtkObject *accessible; - - g_return_val_if_fail (G_IS_OBJECT (obj), NULL); - - accessible = foo_canvas_item_accessible_create (obj); - - return accessible; -} - -static void -foo_canvas_item_accessible_factory_class_init (AtkObjectFactoryClass *klass) -{ - klass->create_accessible = foo_canvas_item_accessible_factory_create_accessible; - klass->get_accessible_type = foo_canvas_item_accessible_factory_get_accessible_type; -} - -static GType -foo_canvas_item_accessible_factory_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo tinfo = { - sizeof (AtkObjectFactoryClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) foo_canvas_item_accessible_factory_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (AtkObjectFactory), - 0, /* n_preallocs */ - NULL - }; - type = g_type_register_static (ATK_TYPE_OBJECT_FACTORY, - "FooCanvasItemAccessibilityFactory", - &tinfo, 0); - } - - return type; -} - -/* Class initialization function for FooCanvasItemClass */ -static void -foo_canvas_item_class_init (FooCanvasItemClass *class) -{ - GObjectClass *gobject_class; - - gobject_class = (GObjectClass *) class; - - item_parent_class = gtk_type_class (gtk_object_get_type ()); - - gobject_class->set_property = foo_canvas_item_set_property; - gobject_class->get_property = foo_canvas_item_get_property; - - g_object_class_install_property - (gobject_class, ITEM_PROP_PARENT, - g_param_spec_object ("parent", NULL, NULL, - FOO_TYPE_CANVAS_ITEM, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - - g_object_class_install_property - (gobject_class, ITEM_PROP_VISIBLE, - g_param_spec_boolean ("visible", NULL, NULL, - TRUE, - (G_PARAM_READABLE | G_PARAM_WRITABLE))); - - item_signals[ITEM_EVENT] = - g_signal_new ("event", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (FooCanvasItemClass, event), - boolean_handled_accumulator, NULL, - foo_canvas_marshal_BOOLEAN__BOXED, - G_TYPE_BOOLEAN, 1, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - - gobject_class->dispose = foo_canvas_item_dispose; - - class->realize = foo_canvas_item_realize; - class->unrealize = foo_canvas_item_unrealize; - class->map = foo_canvas_item_map; - class->unmap = foo_canvas_item_unmap; - class->update = foo_canvas_item_update; - - atk_registry_set_factory_type (atk_get_default_registry (), - FOO_TYPE_CANVAS_ITEM, - foo_canvas_item_accessible_factory_get_type ()); -} - -void -foo_canvas_zmap(void) -{ - /* do nothing */ -} - -/* Last edited: Feb 14 15:21 2005 (rds) */ diff --git a/foocanvas/foo-canvas.h b/foocanvas/foo-canvas.h deleted file mode 100755 index 70620d668..000000000 --- a/foocanvas/foo-canvas.h +++ /dev/null @@ -1,540 +0,0 @@ -/* Last edited: Jun 15 08:20 2005 (edgrif) */ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation - * All rights reserved. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with the Gnome Library; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -/* - @NOTATION@ - */ -/* FooCanvas widget - Tk-like canvas widget for Gnome - * - * FooCanvas is basically a port of the Tk toolkit's most excellent canvas - * widget. Tk is copyrighted by the Regents of the University of California, - * Sun Microsystems, and other parties. - * - * - * Authors: Federico Mena <federico@nuclecu.unam.mx> - * Raph Levien <raph@gimp.org> - */ - -#ifndef FOO_CANVAS_H -#define FOO_CANVAS_H - -#include <gtk/gtklayout.h> -#include <gdk/gdkevents.h> -#include <stdarg.h> - -G_BEGIN_DECLS - - -/* "Small" value used by canvas stuff */ -#define FOO_CANVAS_EPSILON 1e-10 - - -/* Macros for building colors that fit in a 32-bit integer. The values are in - * [0, 255]. - */ - -#define FOO_CANVAS_COLOR(r, g, b) ((((int) (r) & 0xff) << 24) \ - | (((int) (g) & 0xff) << 16) \ - | (((int) (b) & 0xff) << 8) \ - | 0xff) - -#define FOO_CANVAS_COLOR_A(r, g, b, a) ((((int) (r) & 0xff) << 24) \ - | (((int) (g) & 0xff) << 16) \ - | (((int) (b) & 0xff) << 8) \ - | ((int) (a) & 0xff)) - - -typedef struct _FooCanvas FooCanvas; -typedef struct _FooCanvasClass FooCanvasClass; -typedef struct _FooCanvasItem FooCanvasItem; -typedef struct _FooCanvasItemClass FooCanvasItemClass; -typedef struct _FooCanvasGroup FooCanvasGroup; -typedef struct _FooCanvasGroupClass FooCanvasGroupClass; - - -/* FooCanvasItem - base item class for canvas items - * - * All canvas items are derived from FooCanvasItem. The only information a - * FooCanvasItem contains is its parent canvas, its parent canvas item group, - * and its bounding box in world coordinates. - * - * Items inside a canvas are organized in a tree of FooCanvasItemGroup nodes - * and FooCanvasItem leaves. Each canvas has a single root group, which can - * be obtained with the foo_canvas_get_root() function. - * - * The abstract FooCanvasItem class does not have any configurable or - * queryable attributes. - */ - -/* Object flags for items */ -enum { - FOO_CANVAS_ITEM_REALIZED = 1 << 4, - FOO_CANVAS_ITEM_MAPPED = 1 << 5, - FOO_CANVAS_ITEM_ALWAYS_REDRAW = 1 << 6, - FOO_CANVAS_ITEM_VISIBLE = 1 << 7, - FOO_CANVAS_ITEM_NEED_UPDATE = 1 << 8, - FOO_CANVAS_ITEM_NEED_DEEP_UPDATE = 1 << 9 -}; - -/* Update flags for items */ -enum { - FOO_CANVAS_UPDATE_REQUESTED = 1 << 0, - FOO_CANVAS_UPDATE_DEEP = 1 << 1 -}; - -#define FOO_TYPE_CANVAS_ITEM (foo_canvas_item_get_type ()) -#define FOO_CANVAS_ITEM(obj) (GTK_CHECK_CAST ((obj), FOO_TYPE_CANVAS_ITEM, FooCanvasItem)) -#define FOO_CANVAS_ITEM_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), FOO_TYPE_CANVAS_ITEM, FooCanvasItemClass)) -#define FOO_IS_CANVAS_ITEM(obj) (GTK_CHECK_TYPE ((obj), FOO_TYPE_CANVAS_ITEM)) -#define FOO_IS_CANVAS_ITEM_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), FOO_TYPE_CANVAS_ITEM)) -#define FOO_CANVAS_ITEM_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), FOO_TYPE_CANVAS_ITEM, FooCanvasItemClass)) - - -struct _FooCanvasItem { - GtkObject object; - - /* Parent canvas for this item */ - FooCanvas *canvas; - - /* Parent canvas group for this item (a FooCanvasGroup) */ - FooCanvasItem *parent; - - /* Bounding box for this item (in canvas coordinates) */ - double x1, y1, x2, y2; -}; - -struct _FooCanvasItemClass { - GtkObjectClass parent_class; - - /* Tell the item to update itself. The flags are from the update flags - * defined above. The item should update its internal state from its - * queued state, and recompute and request its repaint area. The - * update method also recomputes the bounding box of the item. - */ - void (* update) (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags); - - /* Realize an item -- create GCs, etc. */ - void (* realize) (FooCanvasItem *item); - - /* Unrealize an item */ - void (* unrealize) (FooCanvasItem *item); - - /* Map an item - normally only need by items with their own GdkWindows */ - void (* map) (FooCanvasItem *item); - - /* Unmap an item */ - void (* unmap) (FooCanvasItem *item); - - /* Draw an item of this type. (x, y) are the upper-left canvas pixel - * coordinates of the drawable, a temporary pixmap, where things get - * drawn. (width, height) are the dimensions of the drawable. - */ - void (* draw) (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose); - - /* Calculate the distance from an item to the specified point. It also - * returns a canvas item which is the item itself in the case of the - * object being an actual leaf item, or a child in case of the object - * being a canvas group. (cx, cy) are the canvas pixel coordinates that - * correspond to the item-relative coordinates (x, y). - */ - double (* point) (FooCanvasItem *item, double x, double y, int cx, int cy, - FooCanvasItem **actual_item); - - void (* translate) (FooCanvasItem *item, double dx, double dy); - - /* Fetch the item's bounding box (need not be exactly tight). This - * should be in item-relative coordinates. - */ - void (* bounds) (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2); - - /* Signal: an event ocurred for an item of this type. The (x, y) - * coordinates are in the canvas world coordinate system. - */ - gboolean (* event) (FooCanvasItem *item, GdkEvent *event); - - /* Reserved for future expansion */ - gpointer spare_vmethods [4]; -}; - - -/* Standard Gtk function */ -GType foo_canvas_item_get_type (void) G_GNUC_CONST; - -/* Create a canvas item using the standard Gtk argument mechanism. The item is - * automatically inserted at the top of the specified canvas group. The last - * argument must be a NULL pointer. - */ -FooCanvasItem *foo_canvas_item_new (FooCanvasGroup *parent, GType type, - const gchar *first_arg_name, ...); - -/* Constructors for use in derived classes and language wrappers */ -void foo_canvas_item_construct (FooCanvasItem *item, FooCanvasGroup *parent, - const gchar *first_arg_name, va_list args); - -/* Configure an item using the standard Gtk argument mechanism. The last - * argument must be a NULL pointer. - */ -void foo_canvas_item_set (FooCanvasItem *item, const gchar *first_arg_name, ...); - -/* Used only for language wrappers and the like */ -void foo_canvas_item_set_valist (FooCanvasItem *item, - const gchar *first_arg_name, va_list args); - -/* Move an item by the specified amount */ -void foo_canvas_item_move (FooCanvasItem *item, double dx, double dy); - -/* Raise an item in the z-order of its parent group by the specified number of - * positions. - */ -void foo_canvas_item_raise (FooCanvasItem *item, int positions); - -/* Lower an item in the z-order of its parent group by the specified number of - * positions. - */ -void foo_canvas_item_lower (FooCanvasItem *item, int positions); - -/* Raise an item to the top of its parent group's z-order. */ -void foo_canvas_item_raise_to_top (FooCanvasItem *item); - -/* Lower an item to the bottom of its parent group's z-order */ -void foo_canvas_item_lower_to_bottom (FooCanvasItem *item); - -/* Send an item behind another item */ -void foo_canvas_item_send_behind (FooCanvasItem *item, - FooCanvasItem *behind_item); - - -/* Show an item (make it visible). If the item is already shown, it has no - * effect. - */ -void foo_canvas_item_show (FooCanvasItem *item); - -/* Hide an item (make it invisible). If the item is already invisible, it has - * no effect. - */ -void foo_canvas_item_hide (FooCanvasItem *item); - -/* Grab the mouse for the specified item. Only the events in event_mask will be - * reported. If cursor is non-NULL, it will be used during the duration of the - * grab. Time is a proper X event time parameter. Returns the same values as - * XGrabPointer(). - */ -int foo_canvas_item_grab (FooCanvasItem *item, unsigned int event_mask, - GdkCursor *cursor, guint32 etime); - -/* Ungrabs the mouse -- the specified item must be the same that was passed to - * foo_canvas_item_grab(). Time is a proper X event time parameter. - */ -void foo_canvas_item_ungrab (FooCanvasItem *item, guint32 etime); - -/* These functions convert from a coordinate system to another. "w" is world - * coordinates and "i" is item coordinates. - */ -void foo_canvas_item_w2i (FooCanvasItem *item, double *x, double *y); -void foo_canvas_item_i2w (FooCanvasItem *item, double *x, double *y); - -/* Remove the item from its parent group and make the new group its parent. The - * item will be put on top of all the items in the new group. The item's - * coordinates relative to its new parent to *not* change -- this means that the - * item could potentially move on the screen. - * - * The item and the group must be in the same canvas. An item cannot be - * reparented to a group that is the item itself or that is an inferior of the - * item. - */ -void foo_canvas_item_reparent (FooCanvasItem *item, FooCanvasGroup *new_group); - -/* Used to send all of the keystroke events to a specific item as well as - * GDK_FOCUS_CHANGE events. - */ -void foo_canvas_item_grab_focus (FooCanvasItem *item); - -/* Fetch the bounding box of the item. The bounding box may not be exactly - * tight, but the canvas items will do the best they can. The returned bounding - * box is in the coordinate system of the item's parent. - */ -void foo_canvas_item_get_bounds (FooCanvasItem *item, - double *x1, double *y1, double *x2, double *y2); - -/* Request that the update method eventually get called. This should be used - * only by item implementations. - */ -void foo_canvas_item_request_update (FooCanvasItem *item); - -/* Request a redraw of the bounding box of the canvas item */ -void foo_canvas_item_request_redraw (FooCanvasItem *item); - -/* FooCanvasGroup - a group of canvas items - * - * A group is a node in the hierarchical tree of groups/items inside a canvas. - * Groups serve to give a logical structure to the items. - * - * Consider a circuit editor application that uses the canvas for its schematic - * display. Hierarchically, there would be canvas groups that contain all the - * components needed for an "adder", for example -- this includes some logic - * gates as well as wires. You can move stuff around in a convenient way by - * doing a foo_canvas_item_move() of the hierarchical groups -- to move an - * adder, simply move the group that represents the adder. - * - * The following arguments are available: - * - * name type read/write description - * -------------------------------------------------------------------------------- - * x double RW X coordinate of group's origin - * y double RW Y coordinate of group's origin - */ - - -#define FOO_TYPE_CANVAS_GROUP (foo_canvas_group_get_type ()) -#define FOO_CANVAS_GROUP(obj) (GTK_CHECK_CAST ((obj), FOO_TYPE_CANVAS_GROUP, FooCanvasGroup)) -#define FOO_CANVAS_GROUP_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), FOO_TYPE_CANVAS_GROUP, FooCanvasGroupClass)) -#define FOO_IS_CANVAS_GROUP(obj) (GTK_CHECK_TYPE ((obj), FOO_TYPE_CANVAS_GROUP)) -#define FOO_IS_CANVAS_GROUP_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), FOO_TYPE_CANVAS_GROUP)) -#define FOO_CANVAS_GROUP_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), FOO_TYPE_CANVAS_GROUP, FooCanvasGroupClass)) - - -struct _FooCanvasGroup { - FooCanvasItem item; - - double xpos, ypos; - - /* Children of the group */ - GList *item_list; - GList *item_list_end; -}; - -struct _FooCanvasGroupClass { - FooCanvasItemClass parent_class; -}; - - -/* Standard Gtk function */ -GType foo_canvas_group_get_type (void) G_GNUC_CONST; - - -/*** FooCanvas ***/ - - -#define FOO_TYPE_CANVAS (foo_canvas_get_type ()) -#define FOO_CANVAS(obj) (GTK_CHECK_CAST ((obj), FOO_TYPE_CANVAS, FooCanvas)) -#define FOO_CANVAS_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), FOO_TYPE_CANVAS, FooCanvasClass)) -#define FOO_IS_CANVAS(obj) (GTK_CHECK_TYPE ((obj), FOO_TYPE_CANVAS)) -#define FOO_IS_CANVAS_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), FOO_TYPE_CANVAS)) -#define FOO_CANVAS_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), FOO_TYPE_CANVAS, FooCanvasClass)) - - -struct _FooCanvas { - GtkLayout layout; - - /* Root canvas group */ - FooCanvasItem *root; - - /* The item containing the mouse pointer, or NULL if none */ - FooCanvasItem *current_item; - - /* Item that is about to become current (used to track deletions and such) */ - FooCanvasItem *new_current_item; - - /* Item that holds a pointer grab, or NULL if none */ - FooCanvasItem *grabbed_item; - - /* If non-NULL, the currently focused item */ - FooCanvasItem *focused_item; - - /* GC for temporary draw pixmap */ - GdkGC *pixmap_gc; - - /* Event on which selection of current item is based */ - GdkEvent pick_event; - - /* Scrolling region */ - double scroll_x1, scroll_y1; - double scroll_x2, scroll_y2; - - /* Scaling factor to be used for display */ - double pixels_per_unit_x; - double pixels_per_unit_y; - - /* Idle handler ID */ - guint idle_id; - - /* Signal handler ID for destruction of the root item */ - guint root_destroy_id; - - /* Internal pixel offsets when zoomed out */ - int zoom_xofs, zoom_yofs; - - /* Last known modifier state, for deferred repick when a button is down */ - int state; - - /* Event mask specified when grabbing an item */ - guint grabbed_event_mask; - - /* Tolerance distance for picking items */ - int close_enough; - - /* Whether the canvas should center the canvas in the middle of - * the window if the scroll region is smaller than the window */ - unsigned int center_scroll_region : 1; - - /* Whether items need update at next idle loop iteration */ - unsigned int need_update : 1; - - /* Are we in the midst of an update */ - unsigned int doing_update : 1; - - /* Whether the canvas needs redrawing at the next idle loop iteration */ - unsigned int need_redraw : 1; - - /* Whether current item will be repicked at next idle loop iteration */ - unsigned int need_repick : 1; - - /* For use by internal pick_current_item() function */ - unsigned int left_grabbed_item : 1; - - /* For use by internal pick_current_item() function */ - unsigned int in_repick : 1; -}; - -struct _FooCanvasClass { - GtkLayoutClass parent_class; - - /* Draw the background for the area given. - */ - void (* draw_background) (FooCanvas *canvas, - int x, int y, int width, int height); - - /* Private Virtual methods for groping the canvas inside bonobo */ - void (* request_update) (FooCanvas *canvas); - - /* Reserved for future expansion */ - gpointer spare_vmethods [4]; -}; - - -/* Standard Gtk function */ -GType foo_canvas_get_type (void) G_GNUC_CONST; - -/* Creates a new canvas. You should check that the canvas is created with the - * proper visual and colormap. Any visual will do unless you intend to insert - * gdk_imlib images into it, in which case you should use the gdk_imlib visual. - * - * You should call foo_canvas_set_scroll_region() soon after calling this - * function to set the desired scrolling limits for the canvas. - */ -GtkWidget *foo_canvas_new (void); - -/* Returns the root canvas item group of the canvas */ -FooCanvasGroup *foo_canvas_root (FooCanvas *canvas); - -/* Sets the limits of the scrolling region, in world coordinates */ -void foo_canvas_set_scroll_region (FooCanvas *canvas, - double x1, double y1, double x2, double y2); - -/* Gets the limits of the scrolling region, in world coordinates */ -void foo_canvas_get_scroll_region (FooCanvas *canvas, - double *x1, double *y1, double *x2, double *y2); - -/* Sets the number of pixels that correspond to one unit in world coordinates */ -void foo_canvas_set_pixels_per_unit (FooCanvas *canvas, double n); - -/* Sets the number of pixels corresponding to one unit in world coordinates - * separately on x and y axes, allowing asymmetric zooming. */ -void foo_canvas_set_pixels_per_unit_xy (FooCanvas *canvas, double x, double y); - -/* Wether the canvas centers the scroll region if it is smaller than the window */ -void foo_canvas_set_center_scroll_region (FooCanvas *canvas, gboolean center_scroll_region); - -/* Scrolls the canvas to the specified offsets, given in canvas pixel coordinates */ -void foo_canvas_scroll_to (FooCanvas *canvas, int cx, int cy); - -/* Returns the scroll offsets of the canvas in canvas pixel coordinates. You - * can specify NULL for any of the values, in which case that value will not be - * queried. - */ -void foo_canvas_get_scroll_offsets (FooCanvas *canvas, int *cx, int *cy); - -/* Requests that the canvas be repainted immediately instead of in the idle - * loop. - */ -void foo_canvas_update_now (FooCanvas *canvas); - -/* Returns the item that is at the specified position in world coordinates, or - * NULL if no item is there. - */ -FooCanvasItem *foo_canvas_get_item_at (FooCanvas *canvas, double x, double y); - -/* For use only by item type implementations. Request that the canvas - * eventually redraw the specified region, specified in canvas pixel - * coordinates. The region contains (x1, y1) but not (x2, y2). - */ -void foo_canvas_request_redraw (FooCanvas *canvas, int x1, int y1, int x2, int y2); - -/* These functions convert from a coordinate system to another. "w" is world - * coordinates, "c" is canvas pixel coordinates (pixel coordinates that are - * (0,0) for the upper-left scrolling limit and something else for the - * lower-left scrolling limit). - */ -void foo_canvas_w2c_rect_d (FooCanvas *canvas, - double *x1, double *y1, - double *x2, double *y2); -void foo_canvas_w2c (FooCanvas *canvas, double wx, double wy, int *cx, int *cy); -void foo_canvas_w2c_d (FooCanvas *canvas, double wx, double wy, double *cx, double *cy); -void foo_canvas_c2w (FooCanvas *canvas, int cx, int cy, double *wx, double *wy); - -/* This function takes in coordinates relative to the GTK_LAYOUT - * (canvas)->bin_window and converts them to world coordinates. - * These days canvas coordinates and window coordinates are the same, but - * these are left for backwards compat reasons. - */ -void foo_canvas_window_to_world (FooCanvas *canvas, - double winx, double winy, double *worldx, double *worldy); - -/* This is the inverse of foo_canvas_window_to_world() */ -void foo_canvas_world_to_window (FooCanvas *canvas, - double worldx, double worldy, double *winx, double *winy); - -/* Takes a string specification for a color and allocates it into the specified - * GdkColor. If the string is null, then it returns FALSE. Otherwise, it - * returns TRUE. - */ -int foo_canvas_get_color (FooCanvas *canvas, const char *spec, GdkColor *color); - -/* Allocates a color from the RGB value passed into this function. */ -gulong foo_canvas_get_color_pixel (FooCanvas *canvas, - guint rgba); - - -/* Sets the stipple origin of the specified gc so that it will be aligned with - * all the stipples used in the specified canvas. This is intended for use only - * by canvas item implementations. - */ -void foo_canvas_set_stipple_origin (FooCanvas *canvas, GdkGC *gc); - -void foo_canvas_zmap(void); - -G_END_DECLS - - -#endif - -- GitLab