/* This is -*- C -*- */
/* $Id: guppi-object-scatter.c,v 1.3 2002/01/08 06:28:53 trow Exp $ */
/*
* guppi-object-scatter.c
*
* Copyright (C) 2000 EMC Capital Management, Inc.
* Copyright (C) 2001 The Free Software Foundation
*
* 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-seq-scalar-core.h>
#include <guppi-group-state.h>
#include <guppi-group-view.h>
#include <guppi-group-view-layout.h>
#include "guppi-object-scatter.h"
static GtkObjectClass *parent_class = NULL;
enum {
ARG_0,
ARG_X_AXIS_LABEL,
ARG_Y_AXIS_LABEL,
ARG_DATA_SIZE,
ARG_X_DATA,
ARG_Y_DATA,
ARG_MARKER,
ARG_SIZE1,
ARG_SIZE2,
ARG_COLOR_RGBA,
ARG_COLOR_RGB,
ARG_AXIS_LABEL_FONT,
ARG_AXIS_MARKER_FONT
};
static gpointer
generic_memdup (gconstpointer p, gsize N)
{
gpointer cpy = guppi_malloc (N);
memcpy (cpy, p, N);
return cpy;
}
#define memdup(ptr, type, N) ((type *)generic_memdup((ptr),(N)*sizeof(type)))
static void
guppi_object_scatter_get_arg (GtkObject *obj, GtkArg *arg, guint arg_id)
{
switch (arg_id) {
default:
break;
};
}
static void
guppi_object_scatter_set_arg (GtkObject *obj, GtkArg *arg, guint arg_id)
{
GuppiObjectScatter *oscat = GUPPI_OBJECT_SCATTER (obj);
switch (arg_id) {
case ARG_X_AXIS_LABEL:
guppi_strdup (oscat->x_axis_label);
oscat->x_axis_label = guppi_strdup ((gchar *) GTK_VALUE_POINTER (*arg));
break;
case ARG_Y_AXIS_LABEL:
guppi_strdup (oscat->y_axis_label);
oscat->y_axis_label = guppi_strdup ((gchar *) GTK_VALUE_POINTER (*arg));
break;
case ARG_DATA_SIZE:
oscat->data_size = GTK_VALUE_INT (*arg);
if (oscat->data_size <= 0)
g_warning ("illegal data size: %d", oscat->data_size);
break;
case ARG_X_DATA:
guppi_free (oscat->x_data);
if (oscat->data_size <= 0)
g_warning ("x_data: illegal data size %d", oscat->data_size);
else
oscat->x_data =
memdup (GTK_VALUE_POINTER (*arg), double, oscat->data_size);
break;
case ARG_Y_DATA:
guppi_free (oscat->y_data);
if (oscat->data_size <= 0)
g_warning ("y_data: illegal data size %d", oscat->data_size);
else
oscat->y_data =
memdup (GTK_VALUE_POINTER (*arg), double, oscat->data_size);
break;
case ARG_MARKER:
{
GuppiMarker m = guppi_str2marker ((gchar *) GTK_VALUE_POINTER (*arg));
if (m == GUPPI_MARKER_UNKNOWN) {
g_warning ("Unknown marker \"%s\"",
(gchar *) GTK_VALUE_POINTER (*arg));
} else {
const GuppiMarkerInfo *info;
oscat->marker = m;
info = guppi_marker_info (oscat->marker);
g_assert (info != NULL);
oscat->size1 = 1.0;
oscat->size2 = 1.0;
}
}
break;
case ARG_SIZE1:
oscat->size1 = GTK_VALUE_DOUBLE (*arg);
break;
case ARG_SIZE2:
oscat->size2 = GTK_VALUE_DOUBLE (*arg);
break;
case ARG_COLOR_RGBA:
oscat->color = GTK_VALUE_UINT (*arg);
break;
case ARG_COLOR_RGB:
oscat->color = RGB_TO_RGBA (GTK_VALUE_UINT (*arg), 0xff);
break;
case ARG_AXIS_LABEL_FONT:
guppi_refcounting_assign (oscat->axis_label_font,
GNOME_FONT (GTK_VALUE_POINTER (*arg)));
break;
case ARG_AXIS_MARKER_FONT:
guppi_refcounting_assign (oscat->axis_marker_font,
GNOME_FONT (GTK_VALUE_POINTER (*arg)));
break;
default:
g_assert_not_reached ();
break;
}
}
static void
guppi_object_scatter_finalize (GtkObject *obj)
{
GuppiObjectScatter *oscat = GUPPI_OBJECT_SCATTER (obj);
guppi_free (oscat->x_axis_label);
guppi_free (oscat->y_axis_label);
oscat->x_axis_label = NULL;
oscat->y_axis_label = NULL;
guppi_free (oscat->x_data);
oscat->x_data = NULL;
guppi_free (oscat->y_data);
oscat->y_data = NULL;
guppi_unref0 (oscat->axis_label_font);
guppi_unref0 (oscat->axis_marker_font);
if (parent_class->finalize)
parent_class->finalize (obj);
}
/***************************************************************************/
static gpointer
build (GuppiObject *obj, double hsize, double vsize)
{
GuppiObjectScatter *oscat;
GuppiElementState *grp_state;
GuppiGroupView *grp_view;
GnomeFont *axis_label_font;
GnomeFont *axis_marker_font;
GuppiSeqScalar *x_data;
GuppiSeqScalar *y_data;
GuppiElementState *scatter_state = NULL;
GuppiElementState *frame_state = NULL;
GuppiElementState *x_axis_state = NULL;
GuppiElementState *y_axis_state = NULL;
GuppiElementView *scatter_view = NULL;
GuppiElementView *frame_view = NULL;
GuppiElementView *x_axis_view = NULL;
GuppiElementView *y_axis_view = NULL;
gint i;
const double outer_margin = 3.6;
const double inner_gap = 3.6;
g_return_val_if_fail (obj != NULL && GUPPI_IS_OBJECT_SCATTER (obj), NULL);
oscat = GUPPI_OBJECT_SCATTER (obj);
grp_state = guppi_group_state_new ();
grp_view = GUPPI_GROUP_VIEW (guppi_element_state_make_view (grp_state));
guppi_unref0 (grp_state);
axis_label_font = oscat->axis_label_font;
if (axis_label_font == NULL)
axis_label_font = guppi_default_font_medium ();
axis_marker_font = oscat->axis_label_font;
if (axis_marker_font == NULL)
axis_marker_font = guppi_default_font_medium ();
if (oscat->x_data == NULL) {
g_warning ("No x-data specified.");
return NULL;
}
if (oscat->y_data == NULL) {
g_warning ("No y-data specified.");
return NULL;
}
/* Build up our data objects */
x_data = GUPPI_SEQ_SCALAR (guppi_seq_scalar_core_new ());
y_data = GUPPI_SEQ_SCALAR (guppi_seq_scalar_core_new ());
for (i = 0; i < oscat->data_size; ++i) {
guppi_seq_scalar_append (x_data, oscat->x_data[i]);
guppi_seq_scalar_append (y_data, oscat->y_data[i]);
}
/* Build state objects */
x_axis_state = guppi_element_state_new ("axis",
"position", GUPPI_SOUTH,
"legend", oscat->x_axis_label,
"legend_font", axis_label_font,
"major_label_font",
axis_marker_font, NULL);
y_axis_state = guppi_element_state_new ("axis",
"position", GUPPI_WEST,
"legend", oscat->y_axis_label,
"legend_font", axis_label_font,
"major_label_font", axis_marker_font,
NULL);
scatter_state = guppi_element_state_new ("scatter",
"x_data", x_data,
"y_data", y_data,
"color", oscat->color,
"marker", oscat->marker,
"size1", oscat->size1,
"size2", oscat->size2,
NULL);
frame_state = guppi_element_state_new ("frame", NULL);
/* Build view objects */
x_axis_view = guppi_element_state_make_view (x_axis_state);
y_axis_view = guppi_element_state_make_view (y_axis_state);
scatter_view = guppi_element_state_make_view (scatter_state);
frame_view = guppi_element_state_make_view (frame_state);
/* Define our marker types */
guppi_element_view_set_axis_marker_type (GUPPI_ELEMENT_VIEW (scatter_view), GUPPI_X_AXIS, GUPPI_AXIS_SCALAR);
guppi_element_view_set_axis_marker_type (GUPPI_ELEMENT_VIEW (scatter_view), GUPPI_Y_AXIS, GUPPI_AXIS_SCALAR);
/* Define connections */
guppi_element_view_connect_axis_markers (scatter_view, GUPPI_X_AXIS, frame_view, GUPPI_X_AXIS);
guppi_element_view_connect_axis_markers (scatter_view, GUPPI_Y_AXIS, frame_view, GUPPI_Y_AXIS);
guppi_element_view_connect_axis_markers (scatter_view, GUPPI_X_AXIS, x_axis_view, GUPPI_X_AXIS);
guppi_element_view_connect_axis_markers (scatter_view, GUPPI_Y_AXIS, y_axis_view, GUPPI_Y_AXIS);
/* Do layout */
guppi_group_view_layout_flush_top (grp_view, frame_view, outer_margin);
guppi_group_view_layout_flush_right (grp_view, frame_view, outer_margin);
guppi_group_view_layout_horizontally_aligned (grp_view, y_axis_view, frame_view, inner_gap);
guppi_group_view_layout_flush_left (grp_view, y_axis_view, outer_margin);
guppi_group_view_layout_vertically_aligned (grp_view, frame_view, x_axis_view, inner_gap);
guppi_group_view_layout_flush_bottom (grp_view, x_axis_view, outer_margin);
guppi_group_view_layout_same_place (grp_view, frame_view, scatter_view);
guppi_element_view_set_preferred_view (scatter_view, GUPPI_X_AXIS);
guppi_element_view_set_preferred_view (scatter_view, GUPPI_Y_AXIS);
/* Clean up */
guppi_unref0 (x_data);
guppi_unref0 (y_data);
guppi_unref0 (scatter_state);
guppi_unref0 (frame_state);
guppi_unref0 (x_axis_state);
guppi_unref0 (y_axis_state);
return GUPPI_ELEMENT_VIEW (grp_view);
}
/***************************************************************************/
#define add_arg(str, t, symb) \
gtk_object_add_arg_type("GuppiObjectScatter::" str, t, GTK_ARG_WRITABLE, symb)
static void
guppi_object_scatter_class_init (GuppiObjectScatterClass *klass)
{
GtkObjectClass *object_class = (GtkObjectClass *) klass;
GuppiObjectClass *gobj_class = GUPPI_OBJECT_CLASS (klass);
parent_class = gtk_type_class (GUPPI_TYPE_OBJECT);
object_class->get_arg = guppi_object_scatter_get_arg;
object_class->set_arg = guppi_object_scatter_set_arg;
object_class->finalize = guppi_object_scatter_finalize;
gobj_class->build = build;
add_arg ("x_axis_label", GTK_TYPE_POINTER, ARG_X_AXIS_LABEL);
add_arg ("y_axis_label", GTK_TYPE_POINTER, ARG_Y_AXIS_LABEL);
add_arg ("data_size", GTK_TYPE_INT, ARG_DATA_SIZE);
add_arg ("x_data", GTK_TYPE_POINTER, ARG_X_DATA);
add_arg ("y_data", GTK_TYPE_POINTER, ARG_Y_DATA);
add_arg ("marker", GTK_TYPE_POINTER, ARG_MARKER);
add_arg ("size1", GTK_TYPE_DOUBLE, ARG_SIZE1);
add_arg ("size2", GTK_TYPE_DOUBLE, ARG_SIZE2);
add_arg ("color_rgba", GTK_TYPE_UINT, ARG_COLOR_RGBA);
add_arg ("color_rgb", GTK_TYPE_UINT, ARG_COLOR_RGB);
add_arg ("axis_label_font", GTK_TYPE_POINTER, ARG_AXIS_LABEL_FONT);
add_arg ("axis_marker_font", GTK_TYPE_POINTER, ARG_AXIS_MARKER_FONT);
}
static void
guppi_object_scatter_init (GuppiObjectScatter *obj)
{
/* Set some not-totally-unreasonable defaults */
obj->color = RGBA_RED;
obj->marker = GUPPI_MARKER_CIRCLE;
obj->size1 = 1.0;
obj->size2 = 1.0;
}
GtkType guppi_object_scatter_get_type (void)
{
static GtkType guppi_object_scatter_type = 0;
if (!guppi_object_scatter_type) {
static const GtkTypeInfo guppi_object_scatter_info = {
"GuppiObjectScatter",
sizeof (GuppiObjectScatter),
sizeof (GuppiObjectScatterClass),
(GtkClassInitFunc) guppi_object_scatter_class_init,
(GtkObjectInitFunc) guppi_object_scatter_init,
NULL, NULL, (GtkClassInitFunc) NULL
};
guppi_object_scatter_type =
gtk_type_unique (GUPPI_TYPE_OBJECT, &guppi_object_scatter_info);
}
return guppi_object_scatter_type;
}
GtkObject *
guppi_object_scatter_new (void)
{
return GTK_OBJECT (guppi_type_new (guppi_object_scatter_get_type ()));
}
/* $Id: guppi-object-scatter.c,v 1.3 2002/01/08 06:28:53 trow Exp $ */
syntax highlighted by Code2HTML, v. 0.9.1