/* Copyright (C) 1997, 1998, 1999 by Alex Pfaffe (Digital Dawn Graphics Inc) 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _ddgParam_Class_ #define _ddgParam_Class_ #include "util/ddgutil.h" #include "util/ddgstr.h" /* * Class which supports control of a number of parameters. * ddgParams can be controlled via keys. */ class WEXP ddgParam { public: float _value; float _default; float _min; float _max; float _step; float _fstep; float _sstep; float *_vaddr; void (*_update)(ddgParam *p); bool _bool:1; bool _int:1; bool _wrap:1; int _ikey; int _dkey; unsigned char _key; ddgStr _desc; float _adjust( float v, float a, float b) { return (_wrap?ddgUtil::wrap(v,a,b): ddgUtil::clamp(v,a,b)); } public: ddgParam() { init(' ',"--",0.0,0.0,1.0,0.1,0.01,1.0); } ddgParam(unsigned char k, char *d, float v, float i = 0.0, float a = 1.0, float s = 0.1, float ss = 0.01, float fs = 1.0) { init(k,d,v,i,a,s,ss,fs); } ddgParam(unsigned char k, char *d, float* va, float i = 0.0, float a = 1.0, float s = 0.1, float ss = 0.01, float fs = 1.0) { init(k,d,*va,i,a,s,ss,fs,va); } void setBool(void) { _bool = true; _min = 0.0; _max = 1.0; _step = _sstep = _fstep = 1.0; } bool isBool(void) { return _bool; } void setInt(void) { _int = true; } bool isInt(void) { return _int; } float get(void) { return *_vaddr; } float set(float v) { *_vaddr = ddgUtil::clamp(v,_min,_max); doUpdate(); return *_vaddr; } void init( unsigned char k, char *d = "--", float v = 0.0, float i = 0.0, float a = 1.0, float s = 0.1, float ss = 0.01, float fs = 1.0, float *vaddr = NULL) { if (vaddr) _vaddr = vaddr; else _vaddr = &_value; _key = k; *_vaddr = _default = v; _min = i; _max = a; _step = s; _sstep = ss; _fstep = fs; _bool = _int = _wrap = false; _ikey = _dkey = 0; _desc.assign(d); _update = NULL; } float reset(void) { return set(_default); } float incr(void) { return set(_adjust(get()+_step,_min,_max)); } float decr(void) { return set(_adjust(get()-_step,_min,_max)); } float sincr(void) { return set(_adjust(get()+_sstep,_min,_max)); } float sdecr(void) { return set(_adjust(get()-_sstep,_min,_max)); } float fincr(void) { return set(_adjust(get()+_fstep,_min,_max)); } float fdecr(void) { return set(_adjust(get()-_fstep,_min,_max)); } void max( float max ) { _max = max; } void min( float min ) { _min = min; } unsigned char key(void) { return _key; } void desc( char *d ) { _desc.assign(d); } char *desc( void ) { return (_desc.s); } void control( int d, int i = 0) { _ikey = i; _dkey = d; } int controlI( void ) { return _ikey; } int controlD( void ) { return _dkey; } void wrap( bool w ) { _wrap = w; } bool wrap( void ) { return _wrap; } void update( void (*u)(ddgParam*p)) { _update = u; } void doUpdate (void ) { if (_update) _update(this); } }; class WEXP ddgParamF : public ddgParam { public: ddgParamF(unsigned char k, char *d, float v, float i = 0.0, float a = 1.0, float s = 0.1, float ss = 0.01, float fs = 1.0) : ddgParam(k,d,v,i,a,s,ss,fs) { } }; class WEXP ddgParamB : public ddgParam { public: ddgParamB(unsigned char k, char *d, bool v ) : ddgParam(k,d,v?1.0:0.0,0.0,1.0,1.0) { setBool(); } ddgParamB() { setBool(); } void init( unsigned char k, char *d, bool v = false) { ddgParam::init(k,d,v); setBool(); } void set(bool v) { ddgParam::set(v?1.0:0.0); } bool get(void) { return (ddgParam::get() != 0.0); } }; class WEXP ddgParamI : public ddgParam { public: ddgParamI(unsigned char k, char *d, int v, int i, int a, int s = 1, int ss = 1 ) : ddgParam(k,d,v,i,a,s,ss) { setInt(); } ddgParamI() { setInt(); } void init( unsigned char k, char *d, int v, int i, int a, int s = 1, int ss = 1, int fs = 10) { ddgParam::init(k,d,v,i,a,s,ss,fs); setInt(); } int get(void) { return (int) ddgParam::get(); } }; class WEXP ddgParamR : public ddgParamB { public: bool get(void) { bool retval = ddgParam::get() != 0.0; reset(); return retval; } }; class WEXP ddgParamSetNode : public ddgListNode { ddgParam* _p; public: operator ddgParam* () { return _p; } ddgParamSetNode( ddgParam *p ) : _p(p) {} ddgParam *p() { return _p; } }; class WEXP ddgParamSet : public ddgList { typedef ddgList super; public: void add( ddgParam *p ); ddgParam *find(unsigned char k, int sk ) // Search for parameter k { ddgParamSetNode *psn = (ddgParamSetNode *) head(); while( psn && ((k && psn->p()->key() != k) ||(sk != psn->p()->controlI() && sk != psn->p()->controlD())) ) psn = (ddgParamSetNode *) psn->next(); return psn ? psn->p() : 0; } float get(unsigned char k ) { ddgParamSetNode *psn = (ddgParamSetNode *) head(); while( psn && psn->p()->key() != k) psn = (ddgParamSetNode *) psn->next(); return psn ? psn->p()->get() : 0.0f; } void report(void) { ddgParamSetNode *psn = (ddgParamSetNode *) head(); while(psn) { ddgParam *p = psn->p(); cerr << '['; cerr << (p->key() == 0 ? '#' : p->key() ); cerr << ']'; if (p->isBool()) cerr << (p->get() > 0.5 ? 'T':'F'); else if (p->isInt()) cerr << (int) p->get(); else cerr << (float)p->get(); cerr << " " << p->desc() << '\n'; psn = (ddgParamSetNode *) psn->next(); } } void help(void); bool key(unsigned char key, int x, int y, int sk = 0 ); // Add the entries in the given param set to this one. void append ( ddgParamSet *ps ) { ddgParamSetNode *psn = (ddgParamSetNode *) ps->head(); while (psn) { add(psn->p()); psn = (ddgParamSetNode *) psn->next(); } } }; #endif