/* 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 and * Havoc Pennington . * * 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 #include "guppi-curve-calc.h" #include #include #include #include #include #include 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 $ */