/* This is -*- C -*- */
/* $Id: guppi-curve-calc.c,v 1.1 2002/01/08 06:28:59 trow Exp $ */
/*
* calc.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-curve-calc.h"
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-config.h>
#include <libgnome/gnome-i18n.h>
#include <guppi-useful.h>
#include <guppi-memory.h>
#include <guppi-data-plug-in.h>
static GtkObjectClass *parent_class = NULL;
enum {
ARG_0,
ARG_T0,
ARG_T1,
ARG_X_FUNC_C,
ARG_Y_FUNC_C,
ARG_XY_FUNC_C,
ARG_X_USER_DATA,
ARG_Y_USER_DATA,
ARG_X_FUNC,
ARG_Y_FUNC
};
static void
guppi_curve_calc_get_arg (GtkObject *obj, GtkArg *arg, guint arg_id)
{
switch (arg_id) {
default:
break;
};
}
static void
guppi_curve_calc_set_arg (GtkObject *obj, GtkArg *arg, guint arg_id)
{
GuppiCurveCalc *func = GUPPI_CURVE_CALC (obj);
double (*fn1) (double, gpointer);
void (*fn2) (double, double *, double *, gpointer, gpointer);
GuppiFnWrapper *fw;
switch (arg_id) {
case ARG_T0:
if (func->t0 != GTK_VALUE_DOUBLE (*arg)) {
func->t0 = GTK_VALUE_DOUBLE (*arg);
guppi_data_changed (GUPPI_DATA (obj));
}
break;
case ARG_T1:
if (func->t1 != GTK_VALUE_DOUBLE (*arg)) {
func->t1 = GTK_VALUE_DOUBLE (*arg);
guppi_data_changed (GUPPI_DATA (obj));
}
break;
case ARG_X_FUNC_C:
fn1 = (double (*)(double, gpointer)) GTK_VALUE_POINTER (*arg);
if (fn1 != func->x_func) {
func->x_func = fn1;
guppi_data_changed (GUPPI_DATA (obj));
}
break;
case ARG_Y_FUNC_C:
fn1 = (double (*)(double, gpointer)) GTK_VALUE_POINTER (*arg);
if (fn1 != func->y_func) {
func->y_func = fn1;
guppi_data_changed (GUPPI_DATA (obj));
}
break;
case ARG_XY_FUNC_C:
fn2 =
(void (*)(double, double *, double *, gpointer, gpointer))
GTK_VALUE_POINTER (*arg);
if (fn2 != func->xy_func) {
func->xy_func = fn2;
guppi_data_changed (GUPPI_DATA (obj));
}
break;
case ARG_X_USER_DATA:
if (GTK_VALUE_POINTER (*arg) != func->x_user_data) {
func->x_user_data = GTK_VALUE_POINTER (*arg);
guppi_data_changed (GUPPI_DATA (obj));
}
break;
case ARG_Y_USER_DATA:
if (GTK_VALUE_POINTER (*arg) != func->y_user_data) {
func->y_user_data = GTK_VALUE_POINTER (*arg);
guppi_data_changed (GUPPI_DATA (obj));
}
break;
case ARG_X_FUNC:
fw = GUPPI_FN_WRAPPER (GTK_VALUE_POINTER (*arg));
if (fw != func->x_fn_wrapper) {
guppi_refcounting_assign (func->x_fn_wrapper, fw);
guppi_data_changed (GUPPI_DATA (obj));
}
break;
case ARG_Y_FUNC:
fw = GUPPI_FN_WRAPPER (GTK_VALUE_POINTER (*arg));
if (fw != func->y_fn_wrapper) {
guppi_refcounting_assign (func->y_fn_wrapper, fw);
guppi_data_changed (GUPPI_DATA (obj));
}
break;
default:
break;
};
}
static void
guppi_curve_calc_finalize (GtkObject *obj)
{
GuppiCurveCalc *calc = GUPPI_CURVE_CALC (obj);
guppi_unref0 (calc->x_fn_wrapper);
guppi_unref0 (calc->y_fn_wrapper);
if (parent_class->finalize)
parent_class->finalize (obj);
}
/**************************************************************************/
static void
v_curve_bounds (GuppiCurve *curve, double *a, double *b)
{
GuppiCurveCalc *cfi = GUPPI_CURVE_CALC (curve);
if (a)
*a = cfi->t0;
if (b)
*b = cfi->t1;
}
static void
v_curve_get (GuppiCurve *curve, double t, double *x, double *y)
{
GuppiCurveCalc *cfi = GUPPI_CURVE_CALC (curve);
if (cfi->xy_func) {
cfi->xy_func (t, x, y, cfi->x_user_data, cfi->y_user_data);
return;
}
if (x) {
if (cfi->x_fn_wrapper)
*x = guppi_fn_wrapper_eval_d__d (cfi->x_fn_wrapper, t);
else if (cfi->x_func)
*x = cfi->x_func (t, cfi->x_user_data);
else
*x = t; /* default is identity function */
}
if (y) {
if (cfi->y_fn_wrapper)
*y = guppi_fn_wrapper_eval_d__d (cfi->y_fn_wrapper, t);
else if (cfi->y_func)
*y = cfi->y_func (t, cfi->y_user_data);
else
*y = t; /* default is identity function */
}
}
static gboolean
v_curve_clamp (GuppiCurve *curve, double *t0, double *t1,
double x0, double y0, double x1, double y1)
{
GuppiCurveCalc *cfi = GUPPI_CURVE_CALC (curve);
if (cfi->x_fn_wrapper == NULL && cfi->x_func == NULL) {
if (t0) *t0 = x0 - (x1-x0)/20;
if (t1) *t1 = x1 + (x1-x0)/20;
return TRUE;
}
return FALSE;
}
/**************************************************************************/
#define add_arg(str, t, symb) \
gtk_object_add_arg_type("GuppiCurveCalc::" str, t, GTK_ARG_WRITABLE, symb)
static void
guppi_curve_calc_class_init (GuppiCurveCalcClass *klass)
{
GtkObjectClass *object_class = (GtkObjectClass *) klass;
GuppiCurveClass *curve_class = GUPPI_CURVE_CLASS (klass);
GuppiDataClass *data_class = GUPPI_DATA_CLASS (klass);
parent_class = gtk_type_class (GUPPI_TYPE_CURVE);
object_class->get_arg = guppi_curve_calc_get_arg;
object_class->set_arg = guppi_curve_calc_set_arg;
object_class->finalize = guppi_curve_calc_finalize;
data_class->is_leaf_type = TRUE;
curve_class->bounds = v_curve_bounds;
curve_class->get = v_curve_get;
curve_class->clamp = v_curve_clamp;
add_arg ("t0", GTK_TYPE_DOUBLE, ARG_T0);
add_arg ("t1", GTK_TYPE_DOUBLE, ARG_T1);
add_arg ("x_function_C", GTK_TYPE_POINTER, ARG_X_FUNC_C);
add_arg ("y_function_C", GTK_TYPE_POINTER, ARG_Y_FUNC_C);
add_arg ("xy_function_C", GTK_TYPE_POINTER, ARG_XY_FUNC_C);
add_arg ("x_user_data", GTK_TYPE_POINTER, ARG_X_USER_DATA);
add_arg ("y_user_data", GTK_TYPE_POINTER, ARG_X_USER_DATA);
add_arg ("x_function", GTK_TYPE_POINTER, ARG_X_FUNC);
add_arg ("y_function", GTK_TYPE_POINTER, ARG_Y_FUNC);
}
static void
guppi_curve_calc_init (GuppiCurveCalc *obj)
{
obj->t0 = 0;
obj->t1 = 1;
}
GtkType guppi_curve_calc_get_type (void)
{
static GtkType guppi_curve_calc_type = 0;
if (!guppi_curve_calc_type) {
static const GtkTypeInfo guppi_curve_calc_info = {
"GuppiCurveCalc",
sizeof (GuppiCurveCalc),
sizeof (GuppiCurveCalcClass),
(GtkClassInitFunc) guppi_curve_calc_class_init,
(GtkObjectInitFunc) guppi_curve_calc_init,
NULL, NULL, (GtkClassInitFunc) NULL
};
guppi_curve_calc_type =
gtk_type_unique (GUPPI_TYPE_CURVE, &guppi_curve_calc_info);
}
return guppi_curve_calc_type;
}
/**************************************************************************/
#if 0
GuppiData *
guppi_curve_new_calc_parametric (double t0, double t1,
GuppiFnWrapper *x_fn, GuppiFnWrapper *y_fn)
{
g_return_val_if_fail (x_fn != NULL && GUPPI_IS_FN_WRAPPER (x_fn), NULL);
g_return_val_if_fail (y_fn != NULL && GUPPI_IS_FN_WRAPPER (y_fn), NULL);
return guppi_data_new_by_type (GUPPI_TYPE_CURVE,
GUPPI_TYPE_CURVE_CALC,
"t0", MIN (t0, t1),
"t1", MAX (t0, t1),
"x_function", x_fn,
"y_function", y_fn, NULL);
}
GuppiData *
guppi_curve_new_calc_function (double t0, double t1, GuppiFnWrapper *fn)
{
g_return_val_if_fail (fn != NULL && GUPPI_IS_FN_WRAPPER (fn), NULL);
return guppi_data_new_by_type (GUPPI_TYPE_CURVE,
GUPPI_TYPE_CURVE_CALC,
"t0", MIN (t0, t1),
"t1", MAX (t0, t1), "y_function", fn, NULL);
}
#endif
/* $Id: guppi-curve-calc.c,v 1.1 2002/01/08 06:28:59 trow Exp $ */
syntax highlighted by Code2HTML, v. 0.9.1