/* $Id: guppi-scatter-item.c,v 1.33 2001/11/08 06:13:40 trow Exp $ */
/*
* guppi-scatter-item.c
*
* Copyright (C) 1999 EMC Capital Management, Inc.
*
* Developed by Jon Trowbridge <trow@gnu.org> and
* Havoc Pennington <hp@pobox.com>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
#include <config.h>
#include <guppi-useful.h>
#include "guppi-scatter-tools.h"
#include "guppi-scatter-item.h"
static GtkObjectClass *parent_class = NULL;
static void
guppi_scatter_item_destroy (GtkObject * obj)
{
if (parent_class->destroy)
parent_class->destroy (obj);
}
static void
guppi_scatter_item_finalize (GtkObject * obj)
{
GuppiScatterItem *item = GUPPI_SCATTER_ITEM (obj);
guppi_unref0 (item->local_x_visibility_mask);
guppi_unref0 (item->local_y_visibility_mask);
if (parent_class->finalize)
parent_class->finalize (obj);
}
/***************************************************************************/
static gint
query_slack (GuppiCanvasItem *gci)
{
/* We make the implicit assumption that size1 is the radius in points of a bounding
circle around the markers. In general, this isn't a bad assumption. */
GuppiElementState *state = guppi_canvas_item_state (gci);
double sz, sz_scale;
GuppiSeqScalar *sz_data;
GuppiMarker marker;
const GuppiMarkerInfo *info;
gint slack_x, slack_y;
guppi_element_state_get (state,
"marker", &marker,
"size1", &sz,
"data_size1", &sz_data,
"size1_gradient_scale", &sz_scale,
NULL);
info = guppi_marker_info (marker);
if (sz_data) {
sz = guppi_seq_scalar_max (sz_data) * sz_scale;
} else {
sz *= info->size1_default;
}
guppi_canvas_item_pt2c (gci, sz, sz, &slack_x, &slack_y);
return MAX (slack_x, slack_y);
}
static void
update (GuppiCanvasItem *gci, double aff[6], ArtSVP *svp, gint flags)
{
}
typedef struct _GatherInfo GatherInfo;
struct _GatherInfo {
GuppiCanvasItem *item;
GnomeCanvasBuf *buf;
};
static void
gather_pairs_cb (GuppiIndexedPair *pair, gsize N, gpointer closure)
{
GatherInfo *info = closure;
GuppiScatterState *state = GUPPI_SCATTER_STATE (guppi_canvas_item_state (info->item));
GuppiPixbuf *pixbuf;
double scale;
gint x, y;
gsize i = 0;
guint32 color;
scale = guppi_canvas_item_scale (info->item);
for (i = 0; i < N; ++i) {
if (guppi_element_view_valid_vp (guppi_canvas_item_view (info->item), pair[i].x, pair[i].y)) {
pixbuf = guppi_scatter_state_get_point_pixbuf (state, pair[i].i, scale, &color);
if (pixbuf != NULL) {
guppi_canvas_item_vp2c (info->item, pair[i].x, pair[i].y, &x, &y);
/* FIXME: hardwired colormap colors */
guppi_pixbuf_color_mapped_paste (pixbuf, x, y, color, 0xff0000ff, 0x000000ff, 0xff, info->buf);
guppi_pixbuf_unref (pixbuf);
}
}
}
}
static void
render (GuppiCanvasItem *gci, GnomeCanvasBuf *buf)
{
GuppiScatterItem *item;
GuppiScatterState *state;
GuppiElementView *gev;
GuppiSeqScalar *x_data;
GuppiSeqScalar *y_data;
GatherInfo info;
double vx0, vy0, vx1, vy1;
gint slack;
item = GUPPI_SCATTER_ITEM (gci);
state = GUPPI_SCATTER_STATE (guppi_canvas_item_state (gci));
gev = guppi_canvas_item_view (gci);
x_data = guppi_scatter_state_get_x_data (state);
y_data = guppi_scatter_state_get_y_data (state);
if (x_data == NULL || y_data == NULL)
return;
/*
Find the bounding box for the area we are viewing, in plot/view
coordinates. We allow some slack that is based on our estimate of
how big our largest marker can be.
*/
slack = query_slack (gci);
guppi_canvas_item_c2vp (gci, buf->rect.x0 - slack, buf->rect.y0 - slack,
&vx0, &vy0);
guppi_canvas_item_c2vp (gci, buf->rect.x1 + slack, buf->rect.y1 + slack,
&vx1, &vy1);
info.item = gci;
info.buf = buf;
guppi_seq_scalar_gather_pairs (x_data, y_data, vx0, vy0, vx1, vy1, gather_pairs_cb, &info);
}
static void
foreach_class_toolkit (GuppiCanvasItem * item,
void (*fn) (GuppiPlotToolkit *, gpointer),
gpointer user_data)
{
GuppiPlotToolkit *tk;
tk = guppi_scatter_toolkit_drag ();
fn (tk, user_data);
guppi_unref (tk);
tk = guppi_scatter_toolkit_brush ();
fn (tk, user_data);
guppi_unref (tk);
}
/***************************************************************************/
static void
guppi_scatter_item_class_init (GuppiScatterItemClass * klass)
{
GtkObjectClass *object_class;
GuppiCanvasItemClass *gci_class;
GnomeCanvasItemClass *item_class;
object_class = (GtkObjectClass *) klass;
gci_class = GUPPI_CANVAS_ITEM_CLASS (klass);
item_class = GNOME_CANVAS_ITEM_CLASS (klass);
parent_class = gtk_type_class (GUPPI_TYPE_CANVAS_ITEM);
object_class->destroy = guppi_scatter_item_destroy;
object_class->finalize = guppi_scatter_item_finalize;
gci_class->guppi_update = update;
gci_class->guppi_render = render;
gci_class->uses_vp_coordinates = TRUE;
gci_class->foreach_class_toolkit = foreach_class_toolkit;
guppi_canvas_item_class_set_item_class_toolkit (gci_class,
guppi_scatter_toolkit_default ());
}
static void
guppi_scatter_item_init (GuppiScatterItem * si)
{
}
GtkType guppi_scatter_item_get_type (void)
{
static GtkType scatter_item_type = 0;
if (!scatter_item_type) {
static const GtkTypeInfo scatter_item_info = {
"GuppiScatterItem",
sizeof (GuppiScatterItem),
sizeof (GuppiScatterItemClass),
(GtkClassInitFunc) guppi_scatter_item_class_init,
(GtkObjectInitFunc) guppi_scatter_item_init,
NULL, NULL,
(GtkClassInitFunc) NULL
};
scatter_item_type = gtk_type_unique (GUPPI_TYPE_CANVAS_ITEM,
&scatter_item_info);
}
return scatter_item_type;
}
/* $Id: guppi-scatter-item.c,v 1.33 2001/11/08 06:13:40 trow Exp $ */
syntax highlighted by Code2HTML, v. 0.9.1