aboutsummaryrefslogtreecommitdiff
path: root/gui
diff options
context:
space:
mode:
Diffstat (limited to 'gui')
-rwxr-xr-xgui/Makefile49
-rwxr-xr-xgui/envgen.c296
-rwxr-xr-xgui/envgen.h50
-rwxr-xr-xgui/envgen.pd70
-rwxr-xr-xgui/hslider.pd10
-rwxr-xr-xgui/slider.c62
-rwxr-xr-xgui/slider.h439
-rwxr-xr-xgui/slider.pd32
-rwxr-xr-xgui/state.05
-rwxr-xr-xgui/state.14
-rwxr-xr-xgui/state.24
-rwxr-xr-xgui/state.32
-rwxr-xr-xgui/state.c384
-rwxr-xr-xgui/state.list2
-rwxr-xr-xgui/state.pd44
-rwxr-xr-xgui/testsave.19
-rwxr-xr-xgui/testsave.29
-rwxr-xr-xgui/ticker.c337
-rwxr-xr-xgui/ticker.pd11
-rwxr-xr-xgui/toddle.c382
-rwxr-xr-xgui/toddle.pd50
-rwxr-xr-xgui/w_envgen.h452
22 files changed, 2703 insertions, 0 deletions
diff --git a/gui/Makefile b/gui/Makefile
new file mode 100755
index 0000000..469c06d
--- /dev/null
+++ b/gui/Makefile
@@ -0,0 +1,49 @@
+current: nt
+
+
+# TARGETS += stk
+
+VERSION = \"0.16\"
+
+.SUFFIXES: .dll .obj
+# ----------------------- NT ----------------------------
+
+NTOBJECTS = *.obj
+NTDLLS = *.dll
+
+PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo
+
+PDNTINCLUDE = /I. /I..\..\pd\src /I../include
+
+ProgramFiles = C:\Program Files
+PDNTLDIR = "$(ProgramFiles)\Microsoft Visual Studio\Vc98\lib"
+#PDNTLDIR = "C:\Programme\Msdev\Vc98\lib"
+
+PDNTLIB = $(PDNTLDIR)\libc.lib \
+ $(PDNTLDIR)\oldnames.lib \
+ $(PDNTLDIR)\wsock32.lib \
+ $(PDNTLDIR)\kernel32.lib \
+ $(PDNTLDIR)\uuid.lib \
+ ..\..\pd\bin\pd.lib
+
+nt: $(NTOBJECTS)
+ -link /dll $(PDNTLIB) envgen.obj /export:envgen_setup
+ -link /dll $(PDNTLIB) slider.obj /export:slider_setup
+ -link /dll $(PDNTLIB) state.obj /export:state_setup
+ -link /dll $(PDNTLIB) ticker.obj /export:ticker_setup
+ -link /dll $(PDNTLIB) toddle.obj /export:toddle_setup
+ -copy slider.dll hslider.dll
+
+clean:
+ del *.obj
+ del *.dll
+
+
+.c.obj:
+ -cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
+
+.obj.dll:
+
+
+
+
diff --git a/gui/envgen.c b/gui/envgen.c
new file mode 100755
index 0000000..aa644d0
--- /dev/null
+++ b/gui/envgen.c
@@ -0,0 +1,296 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* ------------------------ envgen~ ----------------------------- */
+
+#define NONE 0
+#define ATTACK 1
+#define SUSTAIN 3
+#define STATES 100
+
+#include "envgen.h"
+#include "w_envgen.h"
+
+static t_class *envgen_class;
+
+
+char dumpy[2000];
+
+/* initialize envelope with argument vector */
+
+#include <stdio.h>
+
+/*
+ envgen crashes frequently when reallocating memory ....
+ I really don't know why, it crashes during resizebytes,
+ which means it is unable to realloc() the memory ?????
+ the pointer seems to be ok, I don't know what else could
+ cause the problem. for the moment we prevent from reallocating
+ by setting the STATES variable to 100 */
+
+void envgen_resize(t_envgen* x,int ns)
+{
+ if (ns > x->args) {
+ int newargs = ns*sizeof(t_float);
+
+ x->duration = resizebytes(x->duration,x->args*sizeof(t_float),newargs);
+ x->finalvalues = resizebytes(x->finalvalues,x->args*sizeof(t_float),newargs);
+ x->args = ns;
+ }
+}
+
+
+
+void envgen_totaldur(t_envgen* x,t_float dur)
+{
+ int i;
+ float f = dur/x->duration[x->last_state];
+
+ if (dur < 10) {
+ post("envgen: duration too small %f",dur);
+ return;
+ }
+
+ for (i=1;i<=x->last_state;i++)
+ x->duration[i]*=f;
+}
+
+
+static void envgen_dump(t_envgen* e)
+{
+ t_atom argv[50];
+ int argc= 0;
+ t_atom* a = argv;
+ int i;
+
+ SETFLOAT(a,e->finalvalues[0]);argc++;
+ for (i=1;i <= e->last_state;i++) {
+ SETFLOAT(argv+argc,e->duration[i] - e->duration[i-1]);
+ argc++;
+ SETFLOAT(argv+argc,e->finalvalues[i]);
+ argc++;
+ }
+ outlet_list(e->out2,&s_list,argc,(t_atom*)&argv);
+
+}
+
+void envgen_init(t_envgen *x,int argc,t_atom* argv)
+{
+ t_float* dur;
+ t_float* val;
+ t_float tdur = 0;
+
+ if (!argc) return;
+
+ x->duration[0] = 0;
+
+ x->last_state = argc>>1;
+ envgen_resize(x,argc>>1);
+
+ dur = x->duration;
+ val = x->finalvalues;
+
+ if (argc) {
+ *val = atom_getfloat(argv++);
+ *dur = 0.0;
+ }
+ dur++;val++;argc--;
+ for (;argc > 0;argc--) {
+ tdur += atom_getfloat(argv++);
+#ifdef DEBUG
+ post("dur =%f",tdur);
+#endif
+ *dur++ = tdur;
+ argc--;
+ if (argc > 0)
+ *val++ = atom_getfloat(argv++);
+ else
+ *val++ = 0;
+#ifdef DEBUG
+ post("val =%f",*(val-1));
+#endif
+
+ }
+
+}
+
+
+
+
+
+void envgen_list(t_envgen *x,t_symbol* s, int argc,t_atom* argv)
+{
+ envgen_init(x,argc,argv);
+ if (glist_isvisible(x->w.glist)) {
+ envgen_drawme(x, x->w.glist, 0);
+ }
+}
+
+
+void envgen_float(t_envgen *x, t_floatarg f)
+{
+ int state = 0;
+ while (x->duration[state] < f && state < x->last_state) state++;
+
+ if (state == 0 || f >= x->duration[x->last_state]) {
+ outlet_float(x->x_obj.ob_outlet,x->finalvalues[state]);
+ return;
+ }
+ outlet_float(x->x_obj.ob_outlet,x->finalvalues[state-1] +
+ (f - x->duration[state-1])*
+ (x->finalvalues[state] - x->finalvalues[state-1])/
+ (x->duration[state] - x->duration[state-1]));
+}
+
+
+void envgen_bang(t_envgen *x)
+{
+ t_atom a[2];
+ x->x_time = 0.0;
+
+
+ SETFLOAT(a,x->finalvalues[NONE]);
+ SETFLOAT(a+1,0);
+ outlet_list(x->x_obj.ob_outlet,&s_list,2,(t_atom*)&a);
+
+/* we don't force the first value anymore, so the first value
+ is actually with what we have left off at the end ...
+ this reduces clicks
+*/
+ x->x_state = ATTACK;
+ x->x_val = x->finalvalues[NONE];
+
+ SETFLOAT(a,x->finalvalues[x->x_state]);
+ SETFLOAT(a+1,x->duration[x->x_state]);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,2,(t_atom*)&a);
+ clock_delay(x->x_clock,x->duration[x->x_state]);
+}
+
+
+static void envgen_sustain(t_envgen *x, t_floatarg f)
+{
+ if (f > 0 && f < x->last_state)
+ x->sustain_state = f;
+}
+
+
+static void envgen_tick(t_envgen* x)
+{
+ t_atom a[2];
+ x->x_state++;
+ if (x->x_state <= x->last_state) {
+ float del = x->duration[x->x_state] - x->duration[x->x_state-1];
+ clock_delay(x->x_clock,del);
+ SETFLOAT(a,x->finalvalues[x->x_state]);
+ SETFLOAT(a+1,del);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,2,(t_atom*)&a);
+ }
+ else
+ clock_unset(x->x_clock);
+}
+
+static void envgen_freeze(t_envgen* x, t_floatarg f)
+{
+ x->x_freeze = f;
+}
+
+static void *envgen_new(t_symbol *s,int argc,t_atom* argv)
+{
+ t_envgen *x = (t_envgen *)pd_new(envgen_class);
+
+ x->args = STATES;
+ x->finalvalues = getbytes( x->args*sizeof(t_float));
+ x->duration = getbytes( x->args*sizeof(t_float));
+#ifdef DEBUG
+ post("finalvalues %x",x->finalvalues);
+#endif
+ /* widget */
+
+ x->w.glist = (t_glist*) canvas_getcurrent();
+ if (argc) {
+ x->w.width = atom_getfloat(argv++);
+ argc--;
+ }
+ else
+ x->w.width = 140;
+
+ if (argc) {
+ x->w.height = atom_getfloat(argv++);
+ argc--;
+ }
+ else
+ x->w.height = 200;
+
+
+
+ x->w.grabbed = 0;
+ x->resizing = 0;
+ /* end widget */
+
+ if (argc)
+ envgen_init(x,argc,argv);
+ else {
+ t_atom a[5];
+ SETFLOAT(a,0);
+ SETFLOAT(a+1,50);
+ SETFLOAT(a+2,1);
+ SETFLOAT(a+3,50);
+ SETFLOAT(a+4,0);
+ envgen_init(x,5,a);
+ }
+
+ x->x_val = 0.0;
+ x->x_state = NONE;
+ x->sustain_state = SUSTAIN;
+ x->x_freeze = 0;
+
+ outlet_new(&x->x_obj, &s_float);
+ x->out2 = outlet_new(&x->x_obj, &s_float);
+
+ x->x_clock = clock_new(x, (t_method) envgen_tick);
+ return (x);
+}
+
+
+void envgen_motion(t_envgen *x, t_floatarg dx, t_floatarg dy);
+void envgen_click(t_envgen *x,
+ t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
+ t_floatarg alt);
+void envgen_key(t_envgen *x, t_floatarg f);
+
+
+void envgen_setup(void)
+{
+ envgen_class = class_new(gensym("envgen"), (t_newmethod)envgen_new, 0,
+ sizeof(t_envgen), 0,A_GIMME,0);
+
+ class_addcreator((t_newmethod)envgen_new,gensym("envgen~"),A_GIMME,0);
+ class_addfloat(envgen_class, envgen_float);
+
+ class_addbang(envgen_class,envgen_bang);
+ class_addlist(envgen_class,envgen_list);
+ class_addmethod(envgen_class,(t_method)envgen_sustain,gensym("sustain"),A_FLOAT);
+
+ class_addmethod(envgen_class, (t_method)envgen_click, gensym("click"),
+ A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
+ class_addmethod(envgen_class, (t_method)envgen_motion, gensym("motion"),
+ A_FLOAT, A_FLOAT, 0);
+ class_addmethod(envgen_class, (t_method)envgen_key, gensym("key"),
+ A_FLOAT, 0);
+
+ class_addmethod(envgen_class,(t_method)envgen_totaldur,gensym("duration"),A_FLOAT,NULL);
+ class_addmethod(envgen_class,(t_method)envgen_freeze,gensym("freeze"),A_FLOAT,NULL);
+
+
+ envgen_setwidget();
+ class_setwidget(envgen_class,&envgen_widgetbehavior);
+ class_addmethod(envgen_class,(t_method)envgen_dump,gensym("dump"),A_NULL);
+}
diff --git a/gui/envgen.h b/gui/envgen.h
new file mode 100755
index 0000000..8db6b43
--- /dev/null
+++ b/gui/envgen.h
@@ -0,0 +1,50 @@
+#ifndef __GG_ENVGEN_H__
+#define __GG_ENVGEN_H__
+
+#include "g_canvas.h"
+
+typedef struct _wenvgen {
+ t_glist* glist;
+ int width;
+ int height;
+ int numdoodles;
+ int grabbed; /* for moving points */
+ int pointerx;
+ int pointery;
+} t_wenvgen;
+
+typedef struct _envgen
+{
+ t_object x_obj;
+
+ t_float x_val;
+
+ t_float x_slevel;
+ t_float x_time;
+ int x_state;
+ int last_state;
+ int sustain_state;
+ int envchanged;
+
+ t_float* finalvalues;
+ t_float* duration;
+ t_float totaldur;
+ t_int args; /* get rid of that */
+ t_int resizing;
+
+
+ t_clock* x_clock;
+ t_float x_freeze;
+
+ t_outlet* out2;
+ /* widget parameters */
+ t_wenvgen w;
+} t_envgen;
+
+
+t_widgetbehavior envgen_widgetbehavior;
+void envgen_drawme(t_envgen *x, t_glist *glist, int firsttime);
+int envgen_set_values(t_envgen * x);
+void envgen_resize(t_envgen* x,int ns);
+
+#endif
diff --git a/gui/envgen.pd b/gui/envgen.pd
new file mode 100755
index 0000000..8c537f9
--- /dev/null
+++ b/gui/envgen.pd
@@ -0,0 +1,70 @@
+#N canvas 289 62 893 565 12;
+#X obj 21 239 osc~;
+#X obj 21 214 sig~ 220;
+#X obj 21 269 *~;
+#X floatatom 18 178 0 0 0;
+#X graph graph2 0 -1 44100 1 440 522 840 222;
+#X array array1 44100 float 0;
+#X pop;
+#X obj 21 299 tabwrite~ array1;
+#X msg 695 174 \; array1 resize 44100;
+#X msg 213 123 0 200 1 200 0;
+#X msg 213 67 -1 500 0.7 200;
+#X text 102 4 envgen - A (not so) simple envelope generator;
+#X obj 178 193 envgen 247 144;
+#X msg 213 45 1 100 0.5 100 0.7 100 0.1 100 1;
+#X msg 213 88 0 50 1 10 0 10 1 10 0 10 1 10 0 10 1 10 0 10 1 10 0 10
+1 10 0 10 1 10 0 10 1 10 0 10 1 10 0 10 1 10 0 10 1;
+#X msg 346 156 duration 1000;
+#X msg 448 156 duration 300;
+#X msg 213 155 freeze 1;
+#X msg 279 156 freeze 0;
+#X obj 97 63 metro 2000;
+#X obj 149 345 line~;
+#X obj 97 32 ticker 15 15;
+#X floatatom 36 83 0 0 0;
+#X floatatom 207 346 0 0 0;
+#X text 13 59 indexing;
+#X obj 691 107 state env;
+#X msg 701 45 1;
+#X msg 634 44 save;
+#X msg 736 45 2;
+#X text 21 357 Messages:;
+#X text 20 375 freeze: addition of new breakpoints on/off;
+#X text 21 391 duration: duration in ms;
+#X text 21 407 bang: output pairs suitable for line~;
+#X text 18 446 <float>: output value at time (in ms);
+#X text 20 465 <list>: set breakpoints in;
+#X text 74 481 <val> <dur> <val> <dur> ... <val> format;
+#X msg 448 187 dump;
+#X text 20 426 dump: output a list suitable to input in other envgen
+;
+#X text 19 498 hitting backspace deletes the selected point;
+#X obj 338 346 print dump;
+#X text 19 514 NEW ! clicking in the lower right corner resizes (in
+run mode ????);
+#X text 18 546 (C) 1999 - 2002 Guenter Geiger;
+#X connect 0 0 2 0;
+#X connect 1 0 0 0;
+#X connect 2 0 5 0;
+#X connect 3 0 1 0;
+#X connect 7 0 10 0;
+#X connect 8 0 10 0;
+#X connect 10 0 21 0;
+#X connect 10 0 18 0;
+#X connect 10 1 37 0;
+#X connect 11 0 10 0;
+#X connect 12 0 10 0;
+#X connect 13 0 10 0;
+#X connect 14 0 10 0;
+#X connect 15 0 10 0;
+#X connect 16 0 10 0;
+#X connect 17 0 10 0;
+#X connect 17 0 5 0;
+#X connect 18 0 2 1;
+#X connect 19 0 17 0;
+#X connect 20 0 10 0;
+#X connect 24 0 23 0;
+#X connect 25 0 23 0;
+#X connect 26 0 23 0;
+#X connect 34 0 10 0;
diff --git a/gui/hslider.pd b/gui/hslider.pd
new file mode 100755
index 0000000..dddb288
--- /dev/null
+++ b/gui/hslider.pd
@@ -0,0 +1,10 @@
+#N canvas 330 157 516 263 12;
+#X floatatom 54 83;
+#X text 203 10 Same as slider;
+#X floatatom 54 131;
+#X obj 54 59 hslider 127 0 15;
+#X obj 54 107 hslider 400 0 15;
+#X text 20 226 (C) 1999 - 2000 Guenter Geiger;
+#X connect 0 0 4 0;
+#X connect 3 0 0 0;
+#X connect 4 0 2 0;
diff --git a/gui/slider.c b/gui/slider.c
new file mode 100755
index 0000000..22b3c69
--- /dev/null
+++ b/gui/slider.c
@@ -0,0 +1,62 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/* ------------------------ slider ----------------------------- */
+
+#include "slider.h"
+
+static t_class *slider_class;
+
+
+static void *slider_new(t_floatarg h,t_floatarg o,t_floatarg w,t_floatarg n,t_floatarg horiz)
+{
+ t_slider *x = (t_slider *)pd_new(slider_class);
+ x->x_glist = (t_glist*) canvas_getcurrent();
+
+ if (w) x->x_width = w;
+ else x->x_width = 15;
+ if (h) x->x_height = h - o;
+ else
+ x->x_height = 127;
+ x->x_offset = o;
+ x->x_pos = o;
+ x->x_pos2 = o;
+ x->a_pos.a_type = A_FLOAT;
+ if (n) x->x_num = n;
+ else x->x_num = 1;
+ outlet_new(&x->x_obj, &s_float);
+
+/* make us think we're an atom .. we are one ... this doesn work,
+ because the object resets it .. so we will have to create our own menu entry later */
+/* x->x_obj.te_type = T_ATOM; */
+ x->x_horizontal = horiz;
+
+ return (x);
+}
+
+
+
+void slider_setup(void)
+{
+ slider_class = class_new(gensym("slider"), (t_newmethod)slider_new, 0,
+ sizeof(t_slider), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addbang(slider_class,slider_bang);
+ class_addfloat(slider_class,slider_float);
+
+ class_addmethod(slider_class, (t_method)slider_mark, gensym("mark"),
+ A_FLOAT, 0);
+
+
+ class_addmethod(slider_class, (t_method)slider_click, gensym("click"),
+ A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
+ class_addmethod(slider_class, (t_method)slider_motion, gensym("motion"),
+ A_FLOAT, A_FLOAT, 0);
+ class_addmethod(slider_class, (t_method)slider_set, gensym("set"),
+A_FLOAT, 0);
+ class_addmethod(slider_class, (t_method)slider_type, gensym("type"),A_FLOAT,0);
+
+
+ slider_setwidget();
+ class_setwidget(slider_class,&slider_widgetbehavior);
+}
+
diff --git a/gui/slider.h b/gui/slider.h
new file mode 100755
index 0000000..69c44dd
--- /dev/null
+++ b/gui/slider.h
@@ -0,0 +1,439 @@
+#ifndef __SLIDER_H__
+#define __SLIDER_H__
+
+/* changes for setting width by <dieter@rhiz.org>
+ set message by <dieter@klingt.org>
+*/
+
+#include "ggee.h"
+#include "m_imp.h"
+#include "g_canvas.h"
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#define SPOSITIONS
+#define te_xpos te_xpix
+#define te_ypos te_ypix
+
+typedef struct _slider
+{
+ t_object x_obj;
+ t_atom a_pos;
+ t_atom a_pos2;
+ t_glist * x_glist;
+ int x_width;
+ int x_height;
+ int x_offset;
+ int x_mpos;
+ int x_num;
+ int x_horizontal;
+} t_slider;
+
+#define x_pos a_pos.a_w.w_float
+#define x_pos2 a_pos2.a_w.w_float
+
+
+/* widget helper functions */
+
+static void draw_inlets(t_slider *x, t_glist *glist, int firsttime, int nin, int nout)
+{
+ int n = nin;
+ int nplus, i;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = x->x_obj.te_xpos + (x->x_width - IOWIDTH) * i / nplus;
+ if (firsttime)
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n",
+ glist_getcanvas(glist),
+ onset, x->x_obj.te_ypos + x->x_height - 1,
+ onset + IOWIDTH, x->x_obj.te_ypos + x->x_height,
+ x, i);
+ else
+ sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, x->x_obj.te_ypos + x->x_height - 1,
+ onset + IOWIDTH, x->x_obj.te_ypos + x->x_height);
+ }
+ n = nout;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = x->x_obj.te_xpos + (x->x_width - IOWIDTH) * i / nplus;
+ if (firsttime)
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n",
+ glist_getcanvas(glist),
+ onset, x->x_obj.te_ypos,
+ onset + IOWIDTH, x->x_obj.te_ypos + 1,
+ x, i);
+ else
+ sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, x->x_obj.te_ypos,
+ onset + IOWIDTH, x->x_obj.te_ypos + 1);
+
+ }
+}
+
+
+
+static void slider_update(t_slider *x, t_glist *glist)
+{
+ if (glist_isvisible(glist)) {
+ if (!x->x_horizontal) {
+ sys_vgui(".x%x.c coords %xP \
+%d %d %d %d\n",glist_getcanvas(glist),x,
+ x->x_obj.te_xpos,x->x_obj.te_ypos + x->x_height - (int)x->x_pos + x->x_offset,
+ x->x_obj.te_xpos + x->x_width,x->x_obj.te_ypos + x->x_height - (int)x->x_pos + x->x_offset);
+ sys_vgui(".x%x.c coords %xP2 \
+%d %d %d %d\n",glist_getcanvas(glist),x,
+ x->x_obj.te_xpos,x->x_obj.te_ypos + x->x_height - (int)x->x_pos2 + x->x_offset,
+ x->x_obj.te_xpos + x->x_width,x->x_obj.te_ypos + x->x_height - (int)x->x_pos2 + x->x_offset);
+ }
+ else {
+ sys_vgui(".x%x.c coords %xP \
+%d %d %d %d\n",glist_getcanvas(glist),x,
+ x->x_obj.te_xpos +(int)x->x_pos - x->x_offset ,x->x_obj.te_ypos,
+ x->x_obj.te_xpos +(int)x->x_pos - x->x_offset ,x->x_obj.te_ypos + x->x_height);
+ sys_vgui(".x%x.c coords %xP2 \
+%d %d %d %d\n",glist_getcanvas(glist),x,
+ x->x_obj.te_xpos +(int)x->x_pos2 - x->x_offset ,x->x_obj.te_ypos,
+ x->x_obj.te_xpos +(int)x->x_pos2 - x->x_offset ,x->x_obj.te_ypos + x->x_height);
+ }
+ }
+}
+
+
+static void slider_drawme(t_slider *x, t_glist *glist, int firsttime)
+{
+ if (firsttime) {
+ sys_vgui(".x%x.c create rectangle \
+%d %d %d %d -tags %xS "BACKGROUND"\n",
+ glist_getcanvas(glist),
+ x->x_obj.te_xpos, x->x_obj.te_ypos,
+ x->x_obj.te_xpos + x->x_width, x->x_obj.te_ypos + x->x_height,
+ x);
+ if (!x->x_horizontal) {
+ sys_vgui(".x%x.c create line \
+%d %d %d %d -width 3 -tags %xP\n",glist_getcanvas(glist),
+ x->x_obj.te_xpos,x->x_obj.te_ypos + x->x_height - (int)x->x_pos + x->x_offset,
+ x->x_obj.te_xpos + x->x_width,
+ x->x_obj.te_ypos + x->x_height - (int)x->x_pos + x->x_offset,x);
+
+ sys_vgui(".x%x.c create line \
+%d %d %d %d -width 3 -tags %xP2\n",glist_getcanvas(glist),
+ x->x_obj.te_xpos,x->x_obj.te_ypos + x->x_height - (int)x->x_pos2 + x->x_offset,
+ x->x_obj.te_xpos + x->x_width,
+ x->x_obj.te_ypos + x->x_height - (int)x->x_pos2 + x->x_offset,x);
+ }
+ else {
+ sys_vgui(".x%x.c create line \
+%d %d %d %d -width 3 -tags %xP\n",glist_getcanvas(glist),
+ x->x_obj.te_xpos + (int)x->x_pos + x->x_offset ,x->x_obj.te_ypos,
+ x->x_obj.te_xpos + (int)x->x_pos + x->x_offset,
+ x->x_obj.te_ypos + x->x_height,x );
+ sys_vgui(".x%x.c create line \
+%d %d %d %d -width 3 -tags %xP2\n",glist_getcanvas(glist),
+ x->x_obj.te_xpos + (int)x->x_pos2 + x->x_offset ,x->x_obj.te_ypos,
+ x->x_obj.te_xpos + (int)x->x_pos2 + x->x_offset,
+ x->x_obj.te_ypos + x->x_height,x );
+ }
+ }
+ else {
+ sys_vgui(".x%x.c coords %xS \
+%d %d %d %d\n",
+ glist_getcanvas(glist), x,
+ x->x_obj.te_xpos, x->x_obj.te_ypos,
+ x->x_obj.te_xpos + x->x_width, x->x_obj.te_ypos + x->x_height);
+ slider_update(x, glist);
+ }
+
+ draw_inlets(x, glist, firsttime, 1,1);
+
+}
+
+
+
+
+static void slider_erase(t_slider* x,t_glist* glist)
+{
+ int n;
+ sys_vgui(".x%x.c delete %xS\n",
+ glist_getcanvas(glist), x);
+
+ sys_vgui(".x%x.c delete %xP\n",
+ glist_getcanvas(glist), x);
+
+ sys_vgui(".x%x.c delete %xP2\n",
+ glist_getcanvas(glist), x);
+
+ n = x->x_num;
+
+ while (n--) {
+ sys_vgui(".x%x.c delete %xi%d\n",glist_getcanvas(glist),x,n);
+ sys_vgui(".x%x.c delete %xo%d\n",glist_getcanvas(glist),x,n);
+ }
+}
+
+
+
+/* ------------------------ slider widgetbehaviour----------------------------- */
+
+
+static void slider_getrect(t_gobj *z, t_glist *owner,
+ int *xp1, int *yp1, int *xp2, int *yp2)
+{
+ int width, height;
+ t_slider* s = (t_slider*)z;
+
+
+ width = s->x_width;
+ height = s->x_height;
+ *xp1 = s->x_obj.te_xpos;
+ *yp1 = s->x_obj.te_ypos;
+ *xp2 = s->x_obj.te_xpos + width;
+ *yp2 = s->x_obj.te_ypos + height;
+}
+
+static void slider_displace(t_gobj *z, t_glist *glist,
+ int dx, int dy)
+{
+ t_slider *x = (t_slider *)z;
+ x->x_obj.te_xpos += dx;
+ x->x_obj.te_ypos += dy;
+ slider_drawme(x, glist, 0);
+ canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
+}
+
+static void slider_select(t_gobj *z, t_glist *glist, int state)
+{
+ t_slider *x = (t_slider *)z;
+ sys_vgui(".x%x.c itemconfigure %xS -fill %s\n", glist,
+ x, (state? "blue" : BACKGROUNDCOLOR));
+}
+
+
+static void slider_activate(t_gobj *z, t_glist *glist, int state)
+{
+/* t_text *x = (t_text *)z;
+ t_rtext *y = glist_findrtext(glist, x);
+ if (z->g_pd != gatom_class) rtext_activate(y, state);*/
+}
+
+static void slider_delete(t_gobj *z, t_glist *glist)
+{
+ t_text *x = (t_text *)z;
+ canvas_deletelinesfor(glist_getcanvas(glist), x);
+}
+
+
+static void slider_vis(t_gobj *z, t_glist *glist, int vis)
+{
+ t_slider* s = (t_slider*)z;
+ if (vis)
+ slider_drawme(s, glist, 1);
+ else
+ slider_erase(s,glist);
+}
+
+/* can we use the normal text save function ?? */
+
+static void slider_save(t_gobj *z, t_binbuf *b)
+{
+ t_slider *x = (t_slider *)z;
+ t_symbol* sname;
+ int maxlen,maxwidth;
+
+/* if (!x->x_horizontal) {*/
+ sname = gensym("slider");
+ maxlen = x->x_height + x->x_offset;
+ maxwidth = x->x_width;
+/* }*/
+
+ /* forget hsliders ...
+ else {
+ sname = gensym("hslider");
+ maxlen = x->x_width + x->x_offset;
+ maxwidth = x->x_height;
+ }
+*/
+
+
+ binbuf_addv(b, "ssiisiiii", gensym("#X"),gensym("obj"),
+ (t_int)x->x_obj.te_xpos, (t_int)x->x_obj.te_ypos, sname,maxlen,
+ x->x_offset,maxwidth,x->x_num,x->x_horizontal);
+/* binbuf_addbinbuf(b, x->te_binbuf); */
+ binbuf_addv(b, ";");
+}
+
+
+t_widgetbehavior slider_widgetbehavior;
+
+
+static void slider_motion(t_slider *x, t_floatarg dx, t_floatarg dy)
+{
+ int max;
+
+ if (!x->x_horizontal) {
+ x->x_mpos -= dy;
+ max = (x->x_offset + x->x_height);
+ }
+ else {
+ x->x_mpos += dx;
+ max = (x->x_offset + x->x_width);
+ }
+
+ if (x->x_mpos < x->x_offset)
+ x->x_pos = x->x_offset;
+ else if (x->x_mpos > (max))
+ x->x_pos = (max);
+ else
+ x->x_pos = x->x_mpos;
+
+
+ slider_update(x, x->x_glist);
+ outlet_float(x->x_obj.ob_outlet, x->x_pos);
+
+}
+
+
+static void slider_click(t_slider *x,
+ t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
+ t_floatarg alt)
+{
+
+ if (!x->x_horizontal)
+ x->x_mpos = x->x_pos = x->x_obj.te_ypos + x->x_height + x->x_offset - ypos;
+ else
+ x->x_mpos = x->x_pos = xpos - x->x_obj.te_xpos + x->x_offset;
+
+ slider_update(x, x->x_glist);
+ outlet_float(x->x_obj.ob_outlet, x->x_pos);
+#if (PD_VERSION_MINOR > 31)
+ glist_grab(x->x_glist, &x->x_obj.te_g, slider_motion, 0,xpos, ypos);
+#else
+ glist_grab(x->x_glist, &x->x_obj.te_g, xpos, ypos);
+#endif
+}
+
+
+#if (PD_VERSION_MINOR > 31)
+static int slider_newclick(t_gobj *z, struct _glist *glist,
+ int xpix, int ypix, int shift, int alt, int dbl, int doit)
+{
+ t_slider* x = (t_slider *)z;
+ if (doit)
+ slider_click( x, (t_floatarg)xpix, (t_floatarg)ypix,
+ (t_floatarg)shift, 0, (t_floatarg)alt);
+ return (1);
+}
+#endif
+
+static void slider_setwidget()
+{
+ slider_widgetbehavior.w_getrectfn = slider_getrect;
+ slider_widgetbehavior.w_displacefn = slider_displace;
+ slider_widgetbehavior.w_selectfn = slider_select;
+ slider_widgetbehavior.w_activatefn = slider_activate;
+ slider_widgetbehavior.w_deletefn = slider_delete;
+ slider_widgetbehavior.w_visfn = slider_vis;
+#if (PD_VERSION_MINOR > 31)
+ slider_widgetbehavior.w_clickfn = slider_newclick;
+ slider_widgetbehavior.w_propertiesfn = NULL;
+#endif
+ slider_widgetbehavior.w_savefn = slider_save;
+}
+
+
+
+static void slider_float(t_slider *x,t_floatarg f)
+{
+ if (!x->x_horizontal) {
+ if (f >= x->x_offset && f <= (x->x_offset + x->x_height))
+ x->x_pos = (int)f;
+ }
+ else
+ if (f >= x->x_offset && f <= (x->x_offset + x->x_width))
+ x->x_pos = (int)f;
+
+
+ slider_update(x, x->x_glist);
+ outlet_float(x->x_obj.ob_outlet, x->x_pos);
+
+}
+
+
+static void slider_mark(t_slider *x,t_floatarg val)
+{
+ if (!x->x_horizontal) {
+ if (val >= x->x_offset && val <= (x->x_offset + x->x_height))
+ x->x_pos2 = (int)val;
+ }
+ else
+ if (val >= x->x_offset && val <= (x->x_offset + x->x_width))
+ x->x_pos2 = (int)val;
+
+ slider_update(x, x->x_glist);
+}
+
+
+static void slider_type(t_slider *x,t_floatarg val)
+{
+ x->x_horizontal=val;
+ slider_vis((struct _gobj*)x,x->x_glist,0);
+ slider_vis((struct _gobj*)x,x->x_glist,1);
+}
+
+static void slider_list(t_slider *x,t_symbol* s,t_int argc, t_atom* argv)
+{
+ t_float num;
+ t_float val;
+
+ if (argc != 2) return;
+
+ num = atom_getfloat(argv++);
+ val = atom_getfloat(argv);
+ if (!x->x_horizontal) {
+ if (val >= x->x_offset && val <= (x->x_offset + x->x_height))
+ if (num)
+ x->x_pos2 = (int)val;
+ else
+ x->x_pos = (int)val;
+ }
+ else
+ if (val >= x->x_offset && val <= (x->x_offset + x->x_width))
+ if (num)
+ x->x_pos2 = (int)val;
+ else
+ x->x_pos = (int)val;
+
+ slider_update(x, x->x_glist);
+ outlet_float(x->x_obj.ob_outlet, x->x_pos);
+
+}
+
+
+
+static void slider_bang(t_slider *x)
+{
+ outlet_float(x->x_obj.ob_outlet, x->x_pos);
+}
+
+
+static void slider_set(t_slider *x,t_floatarg f)
+{
+ if (!x->x_horizontal) {
+ if (f >= x->x_offset && f <= (x->x_offset + x->x_height))
+ x->x_pos = (int)f;
+ }
+ else{
+ if (f >= x->x_offset && f <= (x->x_offset + x->x_width))
+ x->x_pos = (int)f;
+ }
+
+ slider_update(x, x->x_glist);
+}
+
+#endif
diff --git a/gui/slider.pd b/gui/slider.pd
new file mode 100755
index 0000000..23af752
--- /dev/null
+++ b/gui/slider.pd
@@ -0,0 +1,32 @@
+#N canvas 552 205 602 446 12;
+#X obj 14 121 slider 127 0 15 1;
+#X floatatom 12 42 0 0 0;
+#X floatatom 14 319 0 0 0;
+#X obj 12 64 metro 200;
+#X floatatom 121 253 0 0 0;
+#X text 11 23 Alt-Click on number box to toggle between 0 and non-0
+state;
+#X obj 118 142 slider 200 100 15 1;
+#X text 141 139 This was instantiated with "slider 200 100";
+#X obj 14 85 random 127;
+#X obj 304 257 state sl;
+#X msg 304 197 save;
+#X msg 356 197 1;
+#X obj 191 239 slider 100 0 30 1;
+#X text 118 49 Instantiate a new slider with Put->Object and type slider
+into the object. The slider takes up to 3 parameters \, the first is
+the maximum value \, the second is the minimum. The third is the width
+of the slider (contributed by Dieter <dieter@rhiz.org>. Currently only
+integer values are supported.;
+#X msg 178 192 mark 120;
+#X msg 257 285 type 1;
+#X obj 257 315 slider 127 0 15 1;
+#X connect 0 0 2 0;
+#X connect 1 0 3 0;
+#X connect 3 0 8 0;
+#X connect 6 0 4 0;
+#X connect 8 0 0 0;
+#X connect 10 0 9 0;
+#X connect 11 0 9 0;
+#X connect 14 0 6 0;
+#X connect 15 0 16 0;
diff --git a/gui/state.0 b/gui/state.0
new file mode 100755
index 0000000..95acef8
--- /dev/null
+++ b/gui/state.0
@@ -0,0 +1,5 @@
+33.000000
+83.000000
+-49.000000
+0.000000
+2 0.000000 86.500000 0.980000 13.500000 0.000000
diff --git a/gui/state.1 b/gui/state.1
new file mode 100755
index 0000000..9348e8a
--- /dev/null
+++ b/gui/state.1
@@ -0,0 +1,4 @@
+26.000000
+76.000000
+10.000000
+4 0.000000 8.500000 0.770000 52.000000 0.410000 26.000000 0.980000 13.500000 0.000000
diff --git a/gui/state.2 b/gui/state.2
new file mode 100755
index 0000000..31d1cc2
--- /dev/null
+++ b/gui/state.2
@@ -0,0 +1,4 @@
+66.000000
+35.000000
+-27.000000
+2 0.000000 8.500000 0.770000 91.500000 0.000000
diff --git a/gui/state.3 b/gui/state.3
new file mode 100755
index 0000000..5f642cc
--- /dev/null
+++ b/gui/state.3
@@ -0,0 +1,2 @@
+66.000000
+0.000000
diff --git a/gui/state.c b/gui/state.c
new file mode 100755
index 0000000..22abdd2
--- /dev/null
+++ b/gui/state.c
@@ -0,0 +1,384 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+/*
+ * The iem stuff doesn't work yet !!!
+*/
+
+typedef struct _iem_fstyle_flags
+{
+ unsigned int x_font_style:6;
+ unsigned int x_rcv_able:1;
+ unsigned int x_snd_able:1;
+ unsigned int x_lab_is_unique:1;
+ unsigned int x_rcv_is_unique:1;
+ unsigned int x_snd_is_unique:1;
+ unsigned int x_lab_arg_tail_len:6;
+ unsigned int x_lab_is_arg_num:6;
+ unsigned int x_shiftdown:1;
+ unsigned int x_selected:1;
+ unsigned int x_finemoved:1;
+ unsigned int x_put_in2out:1;
+ unsigned int x_change:1;
+ unsigned int x_thick:1;
+ unsigned int x_lin0_log1:1;
+ unsigned int x_steady:1;
+ unsigned int dummy:1;
+} t_iem_fstyle_flags;
+
+typedef struct _iem_init_symargs
+{
+ unsigned int x_loadinit:1;
+ unsigned int x_rcv_arg_tail_len:6;
+ unsigned int x_snd_arg_tail_len:6;
+ unsigned int x_rcv_is_arg_num:6;
+ unsigned int x_snd_is_arg_num:6;
+ unsigned int x_scale:1;
+ unsigned int x_flashed:1;
+ unsigned int x_locked:1;
+ unsigned int dummy:4;
+} t_iem_init_symargs;
+
+
+typedef struct _iemgui
+{
+ t_object x_obj;
+ void *x_glist;
+ void* x_draw;
+ int x_h;
+ int x_w;
+ int x_ldx;
+ int x_ldy;
+ char x_font[16];
+ t_iem_fstyle_flags x_fsf;
+ int x_fontsize;
+ t_iem_init_symargs x_isa;
+ int x_fcol;
+ int x_bcol;
+ int x_lcol;
+ int x_unique_num;
+ t_symbol *x_snd;
+ t_symbol *x_rcv;
+ t_symbol *x_lab;
+} t_iemgui;
+
+
+
+/* hacks .... this duplicates definitions in pd and must be
+ * adjusted if something changes there !!!! */
+
+#define EMPTYSYMBOL "emptysymbol"
+
+typedef struct _mygatom
+{
+ t_text a_text;
+ t_atom a_atom;
+} t_mygatom; /* this is not !! the real t_atom ...*/
+
+#define TATOM(a) (&((t_mygatom*)a)->a_atom)
+
+
+/* glist's are not visible, but the only thing we need is to
+ get the list link from them */
+
+typedef struct _myglist
+{
+ t_object gl_gobj;
+ t_gobj* g_list;
+} t_myglist;
+
+#define FIRSTOBJECT(a) (((t_myglist*)a)->g_list)
+
+
+#ifndef vmess
+#define vmess pd_vmess
+#endif
+
+
+/* ------------------------ State ----------------------------- */
+
+#include "envgen.h"
+
+
+static t_class *state_class;
+
+
+typedef struct _state
+{
+ t_object x_obj;
+ t_canvas* x_canvas;
+ t_symbol* x_name;
+ int x_slot;
+ t_symbol* x_symslot;
+ int x_save;
+ int x_loading;
+ t_clock* x_clock;
+} t_state;
+
+
+
+
+void state_dosave(t_state *x)
+{
+ char name[255];
+ FILE* fp;
+ t_text* a;
+ t_symbol* dir;
+ char dirstr[255];
+
+#ifdef NT
+ dir = gensym("");
+#else
+ dir = canvas_getdir(x->x_canvas);
+#endif
+
+ strcpy(dirstr,dir->s_name);
+
+#ifndef NT
+ strcat(dirstr,"/");
+#endif
+
+ if (x->x_symslot)
+ sprintf(name,"%s%s.%s",dirstr,x->x_name->s_name,x->x_symslot->s_name);
+ else
+ sprintf(name,"%s%s.%d",dirstr,x->x_name->s_name,x->x_slot);
+
+ fp = fopen(name,"w");
+ if (!fp) {
+ post("state: unable to open %s",name);
+ return;
+ }
+
+ a = (t_text*)FIRSTOBJECT(x->x_canvas);
+
+ do {
+ if (a->te_type == T_ATOM) {
+ if (TATOM(a)->a_type == A_SYMBOL) {
+ if (strlen(TATOM(a)->a_w.w_symbol->s_name))
+/* fprintf(fp,"%s\n",TATOM(a)->a_w.w_symbol->s_name);*/
+ fprintf(fp,"%s\n",atom_getsymbol(TATOM(a))->s_name);
+ else
+ fprintf(fp,EMPTYSYMBOL"\n");
+ }
+ else {
+ fprintf(fp,"%f\n",atom_getfloat(TATOM(a)));
+ fprintf(stderr,"%f\n",atom_getfloat(TATOM(a)));
+ }
+ }
+
+ /* slider should be an atom as well ... how to do it ? */
+
+ if (!strcmp(class_getname(a->te_pd),"slider")) {
+ float val = atom_getfloat(TATOM(a));
+ fprintf(fp,"%f\n",val);
+ fprintf(stderr,"slider %f\n",atom_getfloat(TATOM(a)));
+ }
+#if 0
+ if (!strcmp(class_getname(a->te_pd),"vsl")) {
+ /* float val = atom_getfloat(TATOM(a));*/
+ float val = *((float*) (((char*)a) + sizeof(t_iemgui) + sizeof(int)));
+ fprintf(fp,"%f\n",val);
+ fprintf(stderr,"vslider %f\n",val);
+ }
+ if (!strcmp(class_getname(a->te_pd),"hsl")) {
+ float val = *((float*) (((char*)a) + sizeof(t_iemgui) + sizeof(int)));
+ fprintf(fp,"%f\n",val);
+ fprintf(stderr,"hslider %f\n",val);
+ }
+#endif
+ if (!strncmp(class_getname(a->te_pd),"envgen",6)) {
+ int i;
+ t_envgen* e = (t_envgen*) a;
+
+ fprintf(fp,"%d ",e->last_state);
+ fprintf(fp,"%f ",e->finalvalues[0]);
+ for (i=1;i <= e->last_state;i++)
+ fprintf(fp,"%f %f ",e->duration[i] - e->duration[i-1],e->finalvalues[i]);
+ fprintf(fp,"\n");
+ }
+
+
+
+ } while ((a = (t_text*)((t_gobj*)a)->g_next));
+ post("state saved to: %s",name);
+
+ fclose(fp);
+
+}
+
+void state_save(t_state *x)
+{
+ x->x_save = 1;
+ clock_delay(x->x_clock,2000);
+}
+
+
+void state_saveoff(t_state *x)
+{
+ x->x_save = 0;
+}
+
+void state_load(t_state *x)
+{
+ char name[255];
+ FILE* fp;
+ t_text* a;
+ t_float in;
+ t_symbol* dir;
+ char dirstr[255];
+
+#ifdef NT
+ dir = gensym("");
+#else
+ dir = canvas_getdir(x->x_canvas);
+#endif
+
+ strcpy(dirstr,dir->s_name);
+
+#ifndef NT
+ strcat(dirstr,"/");
+#endif
+
+
+ if (x->x_symslot)
+ sprintf(name,"%s%s.%s",dirstr,x->x_name->s_name,x->x_symslot->s_name);
+ else
+ sprintf(name,"%s%s.%d",dirstr,x->x_name->s_name,x->x_slot);
+
+ fp = fopen(name,"r");
+ if (!fp) {
+ post("state: unable to open %s",name);
+ return;
+ }
+
+ a = (t_text*) FIRSTOBJECT(x->x_canvas);
+
+ x->x_loading = 1;
+ post("state loading from: %s",name);
+ *name = 0;
+ do {
+ if (a->te_type == T_ATOM ||
+ !strcmp(class_getname(a->te_pd),"slider")
+ /* ||
+ !strcmp(class_getname(a->te_pd),"vsl") ||
+ !strcmp(class_getname(a->te_pd),"hsl" ) */
+ ) {
+ if (TATOM(a)->a_type == A_SYMBOL) {
+ fscanf(fp,"%s",name);
+ if (strcmp(name,EMPTYSYMBOL))
+ vmess((t_pd*)a,gensym("set"),"s",gensym(name));
+ }
+ else {
+ fscanf(fp,"%f",&in);
+ vmess((t_pd*)a,&s_float,"f",in);
+ }
+ }
+
+ if (!strncmp(class_getname(a->te_pd),"envgen",6)) {
+ int i;
+ int end;
+ float val;
+ float dur;
+ t_atom ilist[255];
+
+ fscanf(fp,"%f",&in);
+ end = in;
+
+ fscanf(fp,"%f",&val);
+ SETFLOAT(ilist,val);
+ for (i=1 ;i <= end;i++) {
+ fscanf(fp,"%f",&dur);
+ fscanf(fp,"%f",&val);
+ SETFLOAT(ilist +2*i-1,dur);
+ SETFLOAT(ilist+2*i,val);
+ }
+ pd_typedmess((t_pd*)a,&s_list,2*end+1,ilist);
+ post("ok %d",end);
+ }
+
+
+ } while ((a = (t_text*)((t_gobj*)a)->g_next) && !feof(fp));
+
+ x->x_loading = 0;
+ fclose(fp);
+
+}
+
+void state_float(t_state *x,t_floatarg f)
+{
+ if (x->x_loading) return;
+ x->x_symslot = NULL;
+ x->x_slot = f;
+ if (x->x_save) {
+ x->x_save = 0;
+ state_dosave(x);
+ return;
+ }
+
+ state_load(x);
+}
+
+
+void state_anything(t_state *x,t_symbol* s,t_int argc,t_atom* argv)
+{
+ x->x_symslot = s;
+ if (x->x_save) {
+ x->x_save = 0;
+ state_dosave(x);
+ return;
+ }
+
+ state_load(x);
+}
+
+
+
+void state_bang(t_state *x)
+{
+ if (x->x_symslot) outlet_symbol(x->x_obj.ob_outlet,x->x_symslot);
+ else
+ outlet_float(x->x_obj.ob_outlet,x->x_slot);
+}
+
+
+static void *state_new(t_symbol* name)
+{
+ t_state *x = (t_state *)pd_new(state_class);
+ x->x_canvas = canvas_getcurrent();
+ if (name != &s_)
+ x->x_name = name;
+ else
+ x->x_name = gensym("state");
+
+ x->x_clock = clock_new(x, (t_method)state_saveoff);
+ x->x_slot = 0;
+ x->x_symslot = NULL;
+ x->x_loading = 0;
+ x->x_save = 0;
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+
+
+void state_setup(void)
+{
+ state_class = class_new(gensym("state"), (t_newmethod)state_new, 0,
+ sizeof(t_state), 0,A_DEFSYM,0);
+ class_addfloat(state_class,state_float);
+ class_addmethod(state_class,(t_method) state_save, gensym("save"), 0);
+ class_addanything(state_class,(t_method) state_anything);
+ class_addbang(state_class,state_bang);
+/* class_addmethod(state_class, (t_method)state_load, gensym("load"), 0);*/
+}
+
+
diff --git a/gui/state.list b/gui/state.list
new file mode 100755
index 0000000..5f642cc
--- /dev/null
+++ b/gui/state.list
@@ -0,0 +1,2 @@
+66.000000
+0.000000
diff --git a/gui/state.pd b/gui/state.pd
new file mode 100755
index 0000000..1575e48
--- /dev/null
+++ b/gui/state.pd
@@ -0,0 +1,44 @@
+#N canvas 182 231 789 437 10;
+#X obj 20 393 state;
+#X msg 20 322 save;
+#X floatatom 405 85 5 0 0;
+#X obj 371 291 ticker 15 15;
+#X obj 684 31 slider 127 0 15 1;
+#X obj 654 165 float;
+#X obj 654 136 toddle black 15 15;
+#X floatatom 654 194 5 0 0;
+#X text 87 10 The state object;
+#X text 7 37 With the state object settings within a patch;
+#X text 7 51 can be saved to a file. You can add a name to;
+#X text 7 66 the state (if you have several states in your;
+#X text 7 81 system this might be a good idea).;
+#X text 9 120 Note that the state object has several problems:;
+#X text 8 146 1) you can not delete "saveable objects" without;
+#X text 10 164 making the already saved states bogus;
+#X text 9 190 2) Not all the gui objects are saveable (Which is;
+#X text 8 208 good in some situations \, you might for example not
+;
+#X text 9 226 save the state selecting widget ....;
+#X text 373 8 saveable:;
+#X text 374 66 Numberboxes:;
+#X text 544 10 This is the "slider" object !!:;
+#X text 545 28 (not vslider);
+#X text 369 269 Not saveable:;
+#X obj 396 293 vsl 15 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X text 422 292 ...etc (everything from the menu exept "number");
+#X obj 418 315 hdl 15 1 0 8 empty empty empty 20 8 0 8 -262144 -1 -1
+0;
+#X text 605 410 (C) Guenter Geiger 2002;
+#X obj 373 141 envgen;
+#X msg 29 346 1;
+#X msg 60 346 2;
+#X msg 90 346 3;
+#X text 370 118 envgen;
+#X connect 1 0 0 0;
+#X connect 4 0 5 1;
+#X connect 5 0 7 0;
+#X connect 6 0 5 0;
+#X connect 29 0 0 0;
+#X connect 30 0 0 0;
+#X connect 31 0 0 0;
diff --git a/gui/testsave.1 b/gui/testsave.1
new file mode 100755
index 0000000..da6c429
--- /dev/null
+++ b/gui/testsave.1
@@ -0,0 +1,9 @@
+60.000000
+30.000000
+20.000000
+1800.000000
+6.000000
+symbol
+symbol
+0.000000
+0.000000
diff --git a/gui/testsave.2 b/gui/testsave.2
new file mode 100755
index 0000000..a9cc15c
--- /dev/null
+++ b/gui/testsave.2
@@ -0,0 +1,9 @@
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+symbol
+symbol
+0.000000
+0.000000
diff --git a/gui/ticker.c b/gui/ticker.c
new file mode 100755
index 0000000..b40b1d7
--- /dev/null
+++ b/gui/ticker.c
@@ -0,0 +1,337 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <ggee.h>
+#include <m_pd.h>
+#include "g_canvas.h"
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* ------------------------ ticker ----------------------------- */
+
+#define DEFAULTSIZE 15
+#define DEFAULTCOLOR "black"
+
+static t_class *ticker_class;
+
+typedef struct _ticker
+{
+ t_object x_obj;
+ t_glist * x_glist;
+ int x_width;
+ int x_height;
+ t_float x_on;
+} t_ticker;
+
+/* widget helper functions */
+
+
+static void draw_inlets(t_ticker *x, t_glist *glist, int firsttime, int nin, int nout)
+{
+ int n = nin;
+ int nplus, i;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = x->x_obj.te_xpix + (x->x_width - IOWIDTH) * i / nplus;
+ if (firsttime)
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n",
+ glist_getcanvas(glist),
+ onset, x->x_obj.te_ypix + x->x_height - 1,
+ onset + IOWIDTH, x->x_obj.te_ypix + x->x_height,
+ x, i);
+ else
+ sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, x->x_obj.te_ypix + x->x_height - 1,
+ onset + IOWIDTH, x->x_obj.te_ypix + x->x_height);
+ }
+ n = nout;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = x->x_obj.te_xpix + (x->x_width - IOWIDTH) * i / nplus;
+ if (firsttime)
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n",
+ glist_getcanvas(glist),
+ onset, x->x_obj.te_ypix,
+ onset + IOWIDTH, x->x_obj.te_ypix + 1,
+ x, i);
+ else
+ sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, x->x_obj.te_ypix,
+ onset + IOWIDTH, x->x_obj.te_ypix + 1);
+
+ }
+}
+
+
+
+void ticker_draw(t_ticker *x,t_glist *glist)
+{
+ if (x->x_on) {
+ sys_vgui(".x%x.c create line \
+%d %d %d %d -tags %xB\n",glist_getcanvas(glist),
+ x->x_obj.te_xpix+1,x->x_obj.te_ypix+1,
+ x->x_obj.te_xpix + x->x_width -1,
+ x->x_obj.te_ypix + x->x_height -1,x);
+ sys_vgui(".x%x.c create line \
+%d %d %d %d -tags %xC\n",glist_getcanvas(glist),
+ x->x_obj.te_xpix+1,x->x_obj.te_ypix + x->x_height -1,
+ x->x_obj.te_xpix + x->x_width -1,x->x_obj.te_ypix+1,
+ x);
+
+ }
+ else {
+ sys_vgui(".x%x.c delete %xB\n",
+ glist_getcanvas(glist), x);
+ sys_vgui(".x%x.c delete %xC\n",
+ glist_getcanvas(glist), x);
+ }
+}
+
+
+void ticker_update(t_ticker *x,t_glist *glist)
+{
+ if (glist_isvisible(glist)) {
+ if (x->x_on) {
+ sys_vgui(".x%x.c coords %xB \
+%d %d %d %d\n",glist_getcanvas(glist),
+ x,x->x_obj.te_xpix+1,x->x_obj.te_ypix+1,
+ x->x_obj.te_xpix + x->x_width -1,
+ x->x_obj.te_ypix + x->x_height -1);
+ sys_vgui(".x%x.c coords %xC \
+%d %d %d %d\n",glist_getcanvas(glist),
+ x,x->x_obj.te_xpix+1,x->x_obj.te_ypix + x->x_height -1,
+ x->x_obj.te_xpix + x->x_width -1,x->x_obj.te_ypix+1);
+
+ }
+ }
+}
+
+
+
+void ticker_drawme(t_ticker *x, t_glist *glist, int firsttime)
+{
+ if (firsttime) {
+ sys_vgui(".x%x.c create rectangle \
+%d %d %d %d -tags %xS "BACKGROUND"\n",
+ glist_getcanvas(glist),
+ x->x_obj.te_xpix, x->x_obj.te_ypix,
+ x->x_obj.te_xpix + x->x_width, x->x_obj.te_ypix + x->x_height,
+ x);
+ ticker_draw(x,glist);
+ }
+ else {
+ sys_vgui(".x%x.c coords %xS \
+%d %d %d %d\n",
+ glist_getcanvas(glist), x,
+ x->x_obj.te_xpix, x->x_obj.te_ypix,
+ x->x_obj.te_xpix + x->x_width, x->x_obj.te_ypix + x->x_height);
+ ticker_update(x,glist);
+ }
+
+ draw_inlets(x, glist, firsttime, 1,1);
+
+}
+
+
+
+
+void ticker_erase(t_ticker* x,t_glist* glist)
+{
+ int n;
+ sys_vgui(".x%x.c delete %xS\n",
+ glist_getcanvas(glist), x);
+
+ sys_vgui(".x%x.c delete %xP\n",
+ glist_getcanvas(glist), x);
+
+ n = 1;
+ sys_vgui(".x%x.c delete %xB\n",
+ glist_getcanvas(glist), x);
+ sys_vgui(".x%x.c delete %xC\n",
+ glist_getcanvas(glist), x);
+
+ while (n--) {
+ sys_vgui(".x%x.c delete %xi%d\n",glist_getcanvas(glist),x,n);
+ sys_vgui(".x%x.c delete %xo%d\n",glist_getcanvas(glist),x,n);
+ }
+}
+
+
+
+/* ------------------------ ticker widgetbehaviour----------------------------- */
+
+
+static void ticker_getrect(t_gobj *z, t_glist *owner,
+ int *xp1, int *yp1, int *xp2, int *yp2)
+{
+ int width, height;
+ t_ticker* s = (t_ticker*)z;
+
+
+ width = s->x_width;
+ height = s->x_height;
+ *xp1 = s->x_obj.te_xpix;
+ *yp1 = s->x_obj.te_ypix;
+ *xp2 = s->x_obj.te_xpix + width;
+ *yp2 = s->x_obj.te_ypix + height;
+}
+
+static void ticker_displace(t_gobj *z, t_glist *glist,
+ int dx, int dy)
+{
+ t_ticker *x = (t_ticker *)z;
+ x->x_obj.te_xpix += dx;
+ x->x_obj.te_ypix += dy;
+ ticker_drawme(x, glist, 0);
+ canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
+}
+
+static void ticker_select(t_gobj *z, t_glist *glist, int state)
+{
+ t_ticker *x = (t_ticker *)z;
+ sys_vgui(".x%x.c itemconfigure %xS -fill %s\n", glist,
+ x, (state? "blue" : BACKGROUNDCOLOR));
+}
+
+
+static void ticker_activate(t_gobj *z, t_glist *glist, int state)
+{
+/* t_text *x = (t_text *)z;
+ t_rtext *y = glist_findrtext(glist, x);
+ if (z->g_pd != gatom_class) rtext_activate(y, state);*/
+}
+
+static void ticker_delete(t_gobj *z, t_glist *glist)
+{
+ t_text *x = (t_text *)z;
+ canvas_deletelinesfor(glist_getcanvas(glist), x);
+}
+
+
+static void ticker_vis(t_gobj *z, t_glist *glist, int vis)
+{
+ t_ticker* s = (t_ticker*)z;
+ if (vis)
+ ticker_drawme(s, glist, 1);
+ else
+ ticker_erase(s,glist);
+}
+
+/* can we use the normal text save function ?? */
+
+static void ticker_save(t_gobj *z, t_binbuf *b)
+{
+ t_ticker *x = (t_ticker *)z;
+ binbuf_addv(b, "ssiisii", gensym("#X"),gensym("obj"),
+ (t_int)x->x_obj.te_xpix, (t_int)x->x_obj.te_ypix,
+ gensym("ticker"),x->x_width,x->x_height);
+ binbuf_addv(b, ";");
+}
+
+
+static void ticker_click(t_ticker *x,
+ t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
+ t_floatarg alt)
+{
+ x->x_on = x->x_on == 0.0 ? 1.0:0.0;
+ ticker_draw(x,x->x_glist);
+ outlet_float(x->x_obj.ob_outlet,x->x_on);
+}
+
+#if (PD_VERSION_MINOR > 31)
+static int ticker_newclick(t_gobj *z, struct _glist *glist,
+ int xpix, int ypix, int shift, int alt, int dbl, int doit)
+{
+ if (doit)
+ ticker_click((t_ticker *)z, (t_floatarg)xpix, (t_floatarg)ypix,
+ (t_floatarg)shift, 0, (t_floatarg)alt);
+ return (1);
+}
+#endif
+
+t_widgetbehavior ticker_widgetbehavior;
+
+
+void ticker_size(t_ticker* x,t_floatarg w,t_floatarg h) {
+ x->x_width = w;
+ x->x_height = h;
+ ticker_drawme(x, x->x_glist, 0);
+}
+
+
+static void ticker_bang(t_ticker* x)
+{
+ x->x_on = x->x_on == 0.0 ? 1.0:0.0;
+ if (glist_isvisible(x->x_glist))
+ ticker_draw(x,x->x_glist);
+ outlet_float(x->x_obj.ob_outlet,x->x_on);
+}
+
+static void ticker_float(t_ticker* x,t_floatarg f)
+{
+ x->x_on = f;
+ if (glist_isvisible(x->x_glist))
+ ticker_draw(x,x->x_glist);
+ outlet_float(x->x_obj.ob_outlet,x->x_on);
+}
+
+static void ticker_set(t_ticker* x,t_floatarg f)
+{
+ x->x_on = f;
+}
+
+static void *ticker_new(t_floatarg h,t_floatarg o)
+{
+ t_ticker *x = (t_ticker *)pd_new(ticker_class);
+
+ x->x_glist = (t_glist*) canvas_getcurrent();
+ if (h) x->x_width = h;
+ else
+ x->x_width = DEFAULTSIZE;
+
+ if (o) x->x_height = o;
+ else
+ x->x_height = DEFAULTSIZE;
+
+ x->x_on = 0;
+
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+void ticker_setup(void)
+{
+ ticker_class = class_new(gensym("ticker"), (t_newmethod)ticker_new, 0,
+ sizeof(t_ticker),0, A_DEFFLOAT,A_DEFFLOAT,0);
+
+
+ class_addmethod(ticker_class, (t_method)ticker_click, gensym("click"),
+ A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
+ class_addmethod(ticker_class, (t_method)ticker_size, gensym("size"),
+ A_FLOAT, A_FLOAT, 0);
+
+ class_addfloat(ticker_class, ticker_float);
+ class_addbang(ticker_class,ticker_bang);
+ class_addmethod(ticker_class,(t_method) ticker_set,gensym("set"),A_FLOAT,0);
+ class_setwidget(ticker_class,&ticker_widgetbehavior);
+
+ ticker_widgetbehavior.w_getrectfn = ticker_getrect;
+ ticker_widgetbehavior.w_displacefn = ticker_displace;
+ ticker_widgetbehavior.w_selectfn = ticker_select;
+ ticker_widgetbehavior.w_activatefn = ticker_activate;
+ ticker_widgetbehavior.w_deletefn = ticker_delete;
+ ticker_widgetbehavior.w_visfn = ticker_vis;
+#if (PD_VERSION_MINOR > 31)
+ ticker_widgetbehavior.w_clickfn = ticker_newclick;
+ ticker_widgetbehavior.w_propertiesfn = NULL;
+#endif
+ ticker_widgetbehavior.w_savefn = ticker_save;
+}
+
+
diff --git a/gui/ticker.pd b/gui/ticker.pd
new file mode 100755
index 0000000..b094910
--- /dev/null
+++ b/gui/ticker.pd
@@ -0,0 +1,11 @@
+#N canvas 209 91 456 299 12;
+#X obj 40 154 ticker 15 15;
+#X floatatom 40 184;
+#X obj 40 125 metro 200;
+#X obj 40 16 ticker 100 100;
+#X obj 75 151 ticker 30 50;
+#X text 43 245 (C) 1999 - 2000 Guenter Geiger;
+#X connect 0 0 1 0;
+#X connect 2 0 0 0;
+#X connect 2 0 4 0;
+#X connect 3 0 2 0;
diff --git a/gui/toddle.c b/gui/toddle.c
new file mode 100755
index 0000000..4b46e8d
--- /dev/null
+++ b/gui/toddle.c
@@ -0,0 +1,382 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#include "g_canvas.h"
+#include <ggee.h>
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#define te_xpos te_xpix
+#define te_ypos te_ypix
+
+/* ------------------------ toddle ----------------------------- */
+
+
+
+#define DEFAULTSIZE 15
+#define DEFAULTCOLOR "black"
+
+static t_class *toddle_class;
+
+typedef struct _toddle
+{
+ t_object x_obj;
+ t_glist * x_glist;
+ int x_width;
+ int x_height;
+ t_symbol* x_color;
+ t_clock* x_clock;
+} t_toddle;
+
+/* widget helper functions */
+
+
+void toddle_drawbang(t_toddle *x,t_glist *glist,int on)
+{
+ if (glist_isvisible(glist)) {
+ if (on)
+ sys_vgui(".x%x.c create oval \
+%d %d %d %d -fill %s -tags %xB\n",glist_getcanvas(glist),
+ x->x_obj.te_xpos+1,x->x_obj.te_ypos+1,
+ x->x_obj.te_xpos + x->x_width -1,
+ x->x_obj.te_ypos + x->x_height -1,x->x_color->s_name,x);
+ else
+ sys_vgui(".x%x.c delete %xB\n",
+ glist_getcanvas(glist), x);
+ }
+}
+
+
+
+
+void toddle_drawme(t_toddle *x, t_glist *glist, int firsttime)
+{
+ if (firsttime) {
+#if 0
+ sys_vgui(".x%x.c create line \
+%d %d %d %d %d %d %d %d %d %d -tags %xS\n",
+ glist_getcanvas(glist),
+ x->x_obj.te_xpos, x->x_obj.te_ypos,
+ x->x_obj.te_xpos + x->x_width, x->x_obj.te_ypos,
+ x->x_obj.te_xpos + x->x_width, x->x_obj.te_ypos + x->x_height,
+ x->x_obj.te_xpos, x->x_obj.te_ypos + x->x_height,
+ x->x_obj.te_xpos, x->x_obj.te_ypos,
+ x);
+#endif
+
+ sys_vgui(".x%x.c create rectangle \
+%d %d %d %d -tags %xS "BACKGROUND"\n",
+ glist_getcanvas(glist),
+ x->x_obj.te_xpos, x->x_obj.te_ypos,
+ x->x_obj.te_xpos + x->x_width, x->x_obj.te_ypos + x->x_height,
+ x);
+ sys_vgui(".x%x.c create oval \
+%d %d %d %d -tags %xP\n",glist_getcanvas(glist),
+ x->x_obj.te_xpos+1,x->x_obj.te_ypos+1,
+ x->x_obj.te_xpos + x->x_width -1,
+ x->x_obj.te_ypos + x->x_height -1,x);
+
+ }
+ else {
+#if 0
+ sys_vgui(".x%x.c coords %xS \
+%d %d %d %d %d %d %d %d %d %d\n",
+ glist_getcanvas(glist), x,
+ x->x_obj.te_xpos, x->x_obj.te_ypos,
+ x->x_obj.te_xpos + x->x_width, x->x_obj.te_ypos,
+ x->x_obj.te_xpos + x->x_width, x->x_obj.te_ypos + x->x_height,
+ x->x_obj.te_xpos, x->x_obj.te_ypos + x->x_height,
+ x->x_obj.te_xpos, x->x_obj.te_ypos);
+#endif
+ sys_vgui(".x%x.c coords %xS \
+%d %d %d %d\n",
+ glist_getcanvas(glist), x,
+ x->x_obj.te_xpos, x->x_obj.te_ypos,
+ x->x_obj.te_xpos + x->x_width, x->x_obj.te_ypos + x->x_height);
+
+
+ sys_vgui(".x%x.c coords %xP \
+%d %d %d %d\n",glist_getcanvas(glist),x,
+ x->x_obj.te_xpos+1,x->x_obj.te_ypos+1,
+ x->x_obj.te_xpos + x->x_width-1,
+ x->x_obj.te_ypos + x->x_height-1);
+ }
+
+
+ {
+ int n = 1;
+ int nplus, i;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = x->x_obj.te_xpos + (x->x_width - IOWIDTH) * i / nplus;
+ if (firsttime)
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n",
+ glist_getcanvas(glist),
+ onset, x->x_obj.te_ypos + x->x_height - 1,
+ onset + IOWIDTH, x->x_obj.te_ypos + x->x_height,
+ x, i);
+ else
+ sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, x->x_obj.te_ypos + x->x_height - 1,
+ onset + IOWIDTH, x->x_obj.te_ypos + x->x_height);
+ }
+ n = 1;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = x->x_obj.te_xpos + (x->x_width - IOWIDTH) * i / nplus;
+ if (firsttime)
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n",
+ glist_getcanvas(glist),
+ onset, x->x_obj.te_ypos,
+ onset + IOWIDTH, x->x_obj.te_ypos + 1,
+ x, i);
+ else
+ sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, x->x_obj.te_ypos,
+ onset + IOWIDTH, x->x_obj.te_ypos + 1);
+
+ }
+ }
+
+}
+
+
+
+
+void toddle_erase(t_toddle* x,t_glist* glist)
+{
+ int n;
+ sys_vgui(".x%x.c delete %xS\n",
+ glist_getcanvas(glist), x);
+
+ sys_vgui(".x%x.c delete %xP\n",
+ glist_getcanvas(glist), x);
+
+ n = 1;
+
+ while (n--) {
+ sys_vgui(".x%x.c delete %xi%d\n",glist_getcanvas(glist),x,n);
+ sys_vgui(".x%x.c delete %xo%d\n",glist_getcanvas(glist),x,n);
+ }
+}
+
+
+
+/* ------------------------ toddle widgetbehaviour----------------------------- */
+
+
+static void toddle_getrect(t_gobj *z, t_glist *owner,
+ int *xp1, int *yp1, int *xp2, int *yp2)
+{
+ int width, height;
+ t_toddle* s = (t_toddle*)z;
+
+
+ width = s->x_width;
+ height = s->x_height;
+ *xp1 = s->x_obj.te_xpos;
+ *yp1 = s->x_obj.te_ypos;
+ *xp2 = s->x_obj.te_xpos + width;
+ *yp2 = s->x_obj.te_ypos + height;
+}
+
+static void toddle_displace(t_gobj *z, t_glist *glist,
+ int dx, int dy)
+{
+ t_toddle *x = (t_toddle *)z;
+ x->x_obj.te_xpos += dx;
+ x->x_obj.te_ypos += dy;
+ toddle_drawme(x, glist, 0);
+ canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
+}
+
+static void toddle_select(t_gobj *z, t_glist *glist, int state)
+{
+ t_toddle *x = (t_toddle *)z;
+ sys_vgui(".x%x.c itemconfigure %xS -fill %s\n", glist,
+ x, (state? "blue" : BACKGROUNDCOLOR));
+}
+
+
+static void toddle_activate(t_gobj *z, t_glist *glist, int state)
+{
+/* t_text *x = (t_text *)z;
+ t_rtext *y = glist_findrtext(glist, x);
+ if (z->g_pd != gatom_class) rtext_activate(y, state);*/
+}
+
+static void toddle_delete(t_gobj *z, t_glist *glist)
+{
+ t_text *x = (t_text *)z;
+ canvas_deletelinesfor(glist_getcanvas(glist), x);
+}
+
+
+static void toddle_vis(t_gobj *z, t_glist *glist, int vis)
+{
+ t_toddle* s = (t_toddle*)z;
+ if (vis)
+ toddle_drawme(s, glist, 1);
+ else
+ toddle_erase(s,glist);
+}
+
+/* can we use the normal text save function ?? */
+
+static void toddle_save(t_gobj *z, t_binbuf *b)
+{
+ t_toddle *x = (t_toddle *)z;
+ binbuf_addv(b, "ssiissii", gensym("#X"),gensym("obj"),
+ (t_int)x->x_obj.te_xpos, (t_int)x->x_obj.te_ypos,
+ gensym("toddle"),x->x_color,x->x_width,x->x_height);
+ binbuf_addv(b, ";");
+}
+
+
+t_widgetbehavior toddle_widgetbehavior;
+
+
+void toddle_bang(t_toddle *x)
+{
+ toddle_drawbang(x,x->x_glist,1);
+ outlet_bang(x->x_obj.ob_outlet);
+ clock_delay(x->x_clock, 100);
+}
+
+
+static void toddle_click(t_toddle *x,
+ t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
+ t_floatarg alt)
+{
+ toddle_bang(x);
+}
+
+#if (PD_VERSION_MINOR > 31)
+static int toddle_newclick(t_gobj *z, struct _glist *glist,
+ int xpix, int ypix, int shift, int alt, int dbl, int doit)
+{
+ if (doit)
+ toddle_click((t_toddle *)z, (t_floatarg)xpix, (t_floatarg)ypix,
+ (t_floatarg)shift, 0, (t_floatarg)alt);
+ return (1);
+}
+#endif
+
+void toddle_float(t_toddle *x,t_floatarg f)
+{
+
+ toddle_drawbang(x,x->x_glist,1);
+
+ clock_delay(x->x_clock, 100);
+ outlet_float(x->x_obj.ob_outlet,f);
+}
+
+void toddle_on(t_toddle* x)
+{
+ toddle_drawbang(x,x->x_glist,1);
+}
+
+void toddle_off(t_toddle* x)
+{
+ toddle_drawbang(x,x->x_glist,0);
+}
+
+void toddle_tick(t_toddle* x)
+{
+ toddle_drawbang(x,x->x_glist,0);
+ clock_unset(x->x_clock);
+}
+
+
+void toddle_size(t_toddle* x,t_floatarg w,t_floatarg h) {
+ x->x_width = w;
+ x->x_height = h;
+ toddle_drawme(x, x->x_glist, 0);
+}
+
+void toddle_color(t_toddle* x,t_symbol* col)
+{
+ x->x_color = col;
+ toddle_drawbang(x,x->x_glist,1);
+ clock_delay(x->x_clock, 100);
+/* outlet_bang(x->x_obj.ob_outlet); only bang if there was a bang ..
+ so color black does the same as bang, but doesn't forward the bang
+*/
+}
+
+static void toddle_setwidget()
+{
+ toddle_widgetbehavior.w_getrectfn = toddle_getrect;
+ toddle_widgetbehavior.w_displacefn = toddle_displace;
+ toddle_widgetbehavior.w_selectfn = toddle_select;
+ toddle_widgetbehavior.w_activatefn = toddle_activate;
+ toddle_widgetbehavior.w_deletefn = toddle_delete;
+ toddle_widgetbehavior.w_visfn = toddle_vis;
+#if (PD_VERSION_MINOR > 31)
+ toddle_widgetbehavior.w_clickfn = toddle_newclick;
+ toddle_widgetbehavior.w_propertiesfn = NULL;
+#endif
+ toddle_widgetbehavior.w_savefn = toddle_save;
+}
+
+
+static void *toddle_new(t_symbol* col,t_floatarg h,t_floatarg o)
+{
+ t_toddle *x = (t_toddle *)pd_new(toddle_class);
+
+ x->x_glist = (t_glist*) canvas_getcurrent();
+ if (h) x->x_width = h;
+ else
+ x->x_width = DEFAULTSIZE;
+
+ if (o) x->x_height = o;
+ else
+ x->x_height = DEFAULTSIZE;
+
+ if (col != &s_)
+ x->x_color = col;
+ else
+ x->x_color = gensym(DEFAULTCOLOR);
+ x->x_clock = clock_new(x, (t_method)toddle_tick);
+
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+void toddle_setup(void)
+{
+ toddle_class = class_new(gensym("toddle"), (t_newmethod)toddle_new, 0,
+ sizeof(t_toddle),0, A_DEFSYM,A_DEFFLOAT,A_DEFFLOAT,0);
+
+ class_addcreator((t_newmethod)toddle_new,gensym("bng"),A_DEFSYM,A_DEFFLOAT,A_DEFFLOAT,A_GIMME,0);
+ class_addbang(toddle_class,toddle_bang);
+ class_addfloat(toddle_class,toddle_float);
+
+ class_addmethod(toddle_class, (t_method)toddle_click, gensym("click"),
+ A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
+
+ class_addmethod(toddle_class, (t_method)toddle_size, gensym("size"),
+ A_FLOAT, A_FLOAT, 0);
+
+ class_addmethod(toddle_class, (t_method)toddle_color, gensym("color"),
+ A_SYMBOL, 0);
+
+ class_addmethod(toddle_class, (t_method)toddle_on, gensym("on"), 0);
+
+ class_addmethod(toddle_class, (t_method)toddle_off, gensym("off"), 0);
+
+
+ toddle_setwidget();
+ class_setwidget(toddle_class,&toddle_widgetbehavior);
+}
+
+
diff --git a/gui/toddle.pd b/gui/toddle.pd
new file mode 100755
index 0000000..2c56c53
--- /dev/null
+++ b/gui/toddle.pd
@@ -0,0 +1,50 @@
+#N canvas 194 167 644 497 12;
+#X obj 21 258 toddle blue 50 50;
+#X obj 254 397 toddle magenta 62 67;
+#X obj 21 315 print;
+#X msg 21 232 bang;
+#X msg 254 251 size 15 15;
+#X obj 22 57 toddle black 15 15;
+#X text 333 250 set the size;
+#X text 42 54 default toddle;
+#X obj 22 92 toddle black 40 40;
+#X text 72 105 toddle black 40 40;
+#X obj 22 149 toddle red 15 15;
+#X text 46 148 toddle red;
+#X obj 22 180 toddle green 10 40;
+#X text 43 193 toddle green 10 40;
+#X text 19 460 (C) 1999 Guenter Geiger;
+#X text 232 9 The Toddle object;
+#X text 232 24 ==================;
+#X msg 460 248 size \$1 \$2;
+#X floatatom 460 206 0 0 0;
+#X obj 460 227 pack 1 2;
+#X floatatom 511 206 0 0 0;
+#X msg 460 183 bang;
+#X text 254 155 wow .....;
+#X msg 460 285 color magenta \, bang;
+#X msg 459 306 color red \, bang;
+#X msg 459 328 color slategrey \, bang;
+#X msg 460 350 color darkgreen \, bang;
+#X text 199 52 To create: Put->Object and type in the "toddle";
+#X floatatom 75 231 0 0 0;
+#X text 75 263 toddle is not a "bang";
+#X text 75 278 converter \, but routes;
+#X text 76 294 messages through;
+#X connect 0 0 2 0;
+#X connect 3 0 0 0;
+#X connect 4 0 1 0;
+#X connect 5 0 8 0;
+#X connect 8 0 10 0;
+#X connect 10 0 12 0;
+#X connect 17 0 1 0;
+#X connect 18 0 19 0;
+#X connect 19 0 17 0;
+#X connect 20 0 19 1;
+#X connect 20 0 21 0;
+#X connect 21 0 18 0;
+#X connect 23 0 1 0;
+#X connect 24 0 1 0;
+#X connect 25 0 1 0;
+#X connect 26 0 1 0;
+#X connect 28 0 0 0;
diff --git a/gui/w_envgen.h b/gui/w_envgen.h
new file mode 100755
index 0000000..b815d6c
--- /dev/null
+++ b/gui/w_envgen.h
@@ -0,0 +1,452 @@
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#define abs fabs
+#endif
+
+#include "ggee.h"
+#define BORDER 2
+
+#if 0 /* backwards compatiblity */
+#define text_xpix(a,b) a.te_xpos
+#define text_ypix(a,b) a.te_ypos
+#endif
+
+static void draw_inlets(t_envgen *x, t_glist *glist, int firsttime, int nin, int nout)
+{
+ int n = nin;
+ int nplus, i;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = x->x_obj.te_xpix + (x->w.width - IOWIDTH) * i / nplus - BORDER;
+ if (firsttime)
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n",
+ glist_getcanvas(glist),
+ onset, x->x_obj.te_ypix + x->w.height - 1 + 2*BORDER,
+ onset + IOWIDTH, x->x_obj.te_ypix + x->w.height + 2*BORDER,
+ x, i);
+ else
+ sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, x->x_obj.te_ypix + x->w.height - 1 + 2*BORDER,
+ onset + IOWIDTH, x->x_obj.te_ypix + x->w.height + 2*BORDER);
+ }
+ n = nout;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = x->x_obj.te_xpix + (x->w.width - IOWIDTH) * i / nplus - BORDER;
+ if (firsttime)
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n",
+ glist_getcanvas(glist),
+ onset, x->x_obj.te_ypix - BORDER,
+ onset + IOWIDTH, x->x_obj.te_ypix + 1 - BORDER,
+ x, i);
+ else
+ sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, x->x_obj.te_ypix - BORDER,
+ onset + IOWIDTH, x->x_obj.te_ypix + 1 - BORDER);
+
+ }
+}
+
+
+
+static int envgen_next_doodle(t_envgen *x, int xpos,int ypos)
+{
+ int ret = -1;
+ float xscale,yscale;
+ int dxpos,dypos;
+ float minval = 1000000.0;
+ float tval;
+ int i;
+ int insertpos = -1;
+
+
+ xscale = x->w.width/x->duration[x->last_state];
+ yscale = x->w.height;
+
+ dxpos = x->x_obj.te_xpix;/* + BORDER */;
+ dypos = x->x_obj.te_ypix + BORDER;
+
+ for (i=0;i<=x->last_state;i++) {
+ float dx2 = (dxpos + (x->duration[i] * xscale)) - xpos;
+ float dy2 = (dypos + yscale - (x->finalvalues[i] * yscale)) - ypos;
+
+ dx2*=dx2;
+ dy2*=dy2;
+ tval = dx2+dy2;
+/* post("%i: dist = %f dx=%f dy=%f",i,tval,dx2,dy2);*/
+ if ((dxpos + (x->duration[i] * xscale)) < xpos)
+ insertpos = i;
+ if (abs(tval) < minval) {
+ minval = abs(tval);
+ }
+ }
+
+ /* decide if we want to make a new one */
+/* post("insertpos %d",insertpos); */
+ if (minval > /*5*/ 16 && insertpos >= 0 && !x->x_freeze) {
+
+ if (((dxpos + (x->duration[insertpos] * xscale)) - xpos) < 0)
+ insertpos++;
+/* post("minval = %f, insertpos = %d",minval,insertpos);*/
+
+ if (x->last_state+1 >= x->args)
+ envgen_resize(x,x->args+1);
+
+ for (i=x->last_state;i>=insertpos;i--) {
+ x->duration[i+1] = x->duration[i];
+ x->finalvalues[i+1] = x->finalvalues[i];
+ }
+
+ x->duration[insertpos] = (float)(xpos-dxpos)/x->w.width*x->duration[x->last_state++];
+
+ x->w.grabbed = insertpos;
+ }
+
+ return insertpos;
+}
+
+static void envgen_create_doodles(t_envgen *x, t_glist *glist)
+{
+ float xscale,yscale;
+ int xpos,ypos;
+ int i;
+ char guistr[255];
+
+ xscale = x->w.width/x->duration[x->last_state];
+ yscale = x->w.height;
+
+ xpos = x->x_obj.te_xpix;
+ ypos = (int) (x->x_obj.te_ypix + x->w.height);
+ for (i=0;i<=x->last_state;i++) {
+ sprintf(guistr,".x%x.c create oval %d %d %d %d -tags %xD%d",glist_getcanvas(glist),
+ (int) (xpos+(x->duration[i] * xscale) - 2),
+ (int) (ypos - x->finalvalues[i]*yscale - 2),
+ (int) (xpos+(x->duration[i] * xscale)+2),
+ (int) (ypos - x->finalvalues[i]*yscale + 2),
+ x,i);
+
+ if (i == x->w.grabbed) strcat(guistr," -fill red\n");
+ else strcat(guistr,"\n");
+ sys_vgui("%s",guistr);
+ }
+ x->w.numdoodles = i;
+}
+
+
+static void envgen_delete_doodles(t_envgen *x, t_glist *glist)
+{
+ int i;
+ for (i=0;i<=x->w.numdoodles;i++)
+ sys_vgui(".x%x.c delete %xD%d\n",glist_getcanvas(glist),x,i);
+}
+
+static void envgen_update_doodles(t_envgen *x, t_glist *glist)
+{
+
+ envgen_delete_doodles(x,glist);
+/* LATER only create new doodles if necessary */
+ envgen_create_doodles(x, glist);
+}
+
+
+static void envgen_create(t_envgen *x, t_glist *glist)
+{
+ int i;
+ static char buf[1024];
+ float xscale,yscale;
+ int xpos,ypos;
+ char num[40];
+
+ sys_vgui(".x%x.c create rectangle \
+%d %d %d %d -tags %xS "BACKGROUND"\n",
+ glist_getcanvas(glist),
+ x->x_obj.te_xpix-BORDER, x->x_obj.te_ypix-BORDER,
+ x->x_obj.te_xpix + x->w.width+2*BORDER, x->x_obj.te_ypix + x->w.height+2*BORDER,
+ x);
+
+ xscale = x->w.width/x->duration[x->last_state];
+ yscale = x->w.height;
+
+ sprintf(buf,".x%x.c create line",glist_getcanvas(glist));
+ xpos = x->x_obj.te_xpix;
+ ypos = (int) (x->x_obj.te_ypix + x->w.height);
+ for (i=0;i<=x->last_state;i++) {
+ sprintf(num," %d %d ",(int)(xpos + x->duration[i]*xscale),
+ (int)(ypos - x->finalvalues[i]*yscale));
+ strcat(buf,num);
+ }
+
+ sprintf(num,"-tags %xP\n",x);
+ strcat(buf,num);
+/* post("sending %s",buf); */
+ sys_vgui("%s",buf);
+ envgen_create_doodles(x,glist);
+}
+
+
+static void envgen_update(t_envgen *x, t_glist *glist)
+{
+int i;
+ static char buf[1024];
+ float xscale,yscale;
+ int xpos,ypos;
+ char num[40];
+
+ sys_vgui(".x%x.c coords %xS \
+%d %d %d %d\n",
+ glist_getcanvas(glist), x,
+ x->x_obj.te_xpix - BORDER, x->x_obj.te_ypix -BORDER,
+ x->x_obj.te_xpix + x->w.width+2*BORDER, x->x_obj.te_ypix + x->w.height+2*BORDER);
+
+
+ xscale = x->w.width/x->duration[x->last_state];
+ yscale = x->w.height;
+
+ sprintf(buf,".x%x.c coords %xP",glist_getcanvas(glist),x);
+ xpos = x->x_obj.te_xpix;
+ ypos = (int) (x->x_obj.te_ypix + x->w.height);
+ for (i=0;i<=x->last_state;i++) {
+ sprintf(num," %d %d ",(int)(xpos + x->duration[i]*xscale),
+ (int) (ypos - x->finalvalues[i]*yscale));
+ strcat(buf,num);
+ }
+ strcat(buf,"\n");
+/* post("sending %s",buf); */
+ sys_vgui("%s",buf);
+ envgen_update_doodles(x,glist);
+}
+
+
+
+void envgen_drawme(t_envgen *x, t_glist *glist, int firsttime)
+{
+
+ if (firsttime) envgen_create(x,glist);
+ else envgen_update(x,glist);
+
+ draw_inlets(x, glist, firsttime, 1,1);
+}
+
+
+
+
+void envgen_erase(t_envgen* x,t_glist* glist)
+{
+ int n;
+ sys_vgui(".x%x.c delete %xS\n",
+ glist_getcanvas(glist), x);
+
+ sys_vgui(".x%x.c delete %xP\n",
+ glist_getcanvas(glist), x);
+
+ n = 1;
+
+ while (n--) {
+ sys_vgui(".x%x.c delete %xi%d\n",glist_getcanvas(glist),x,n);
+ sys_vgui(".x%x.c delete %xo%d\n",glist_getcanvas(glist),x,n);
+ }
+
+ envgen_delete_doodles(x,glist);
+}
+
+
+
+/* ------------------------ envgen widgetbehaviour----------------------------- */
+
+
+static void envgen_getrect(t_gobj *z, t_glist *owner,
+ int *xp1, int *yp1, int *xp2, int *yp2)
+{
+ int width, height;
+ t_envgen* s = (t_envgen*)z;
+
+
+ width = s->w.width + 2*BORDER;
+ height = s->w.height + 2*BORDER;
+ *xp1 = s->x_obj.te_xpix-BORDER;
+ *yp1 = s->x_obj.te_ypix-BORDER;
+ *xp2 = s->x_obj.te_xpix + width;
+ *yp2 = s->x_obj.te_ypix + height;
+}
+
+static void envgen_displace(t_gobj *z, t_glist *glist,
+ int dx, int dy)
+{
+ t_envgen *x = (t_envgen *)z;
+ x->x_obj.te_xpix += dx;
+ x->x_obj.te_ypix += dy;
+
+ envgen_drawme(x, glist, 0);
+ canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
+}
+
+static void envgen_select(t_gobj *z, t_glist *glist, int state)
+{
+ t_envgen *x = (t_envgen *)z;
+ sys_vgui(".x%x.c itemconfigure %xS -fill %s\n", glist,
+ x, (state? "blue" : BACKGROUNDCOLOR));
+}
+
+
+static void envgen_activate(t_gobj *z, t_glist *glist, int state)
+{
+/* t_text *x = (t_text *)z;
+ t_rtext *y = glist_findrtext(glist, x);
+ if (z->g_pd != gatom_class) rtext_activate(y, state);*/
+}
+
+static void envgen_delete(t_gobj *z, t_glist *glist)
+{
+ t_text *x = (t_text *)z;
+ canvas_deletelinesfor(glist_getcanvas(glist), x);
+}
+
+
+static void envgen_vis(t_gobj *z, t_glist *glist, int vis)
+{
+ t_envgen* s = (t_envgen*)z;
+ if (vis)
+ envgen_drawme(s, glist, 1);
+ else
+ envgen_erase(s,glist);
+}
+
+/* can we use the normal text save function ?? */
+
+static void envgen_save(t_gobj *z, t_binbuf *b)
+{
+ t_envgen *x = (t_envgen *)z;
+ binbuf_addv(b, "ssiisii", gensym("#X"),gensym("obj"),
+ (t_int)x->x_obj.te_xpix, (t_int)x->x_obj.te_ypix,
+ gensym("envgen"),x->w.width,x->w.height);
+ binbuf_addv(b, ";");
+}
+
+
+
+static void envgen_followpointer(t_envgen* x)
+{
+ float dur;
+
+ float xscale = x->duration[x->last_state]/x->w.width;
+
+ if ((x->w.grabbed > 0) && (x->w.grabbed < x->last_state)) {
+
+ dur = (x->w.pointerx - x->x_obj.te_xpix)*xscale;
+ if (dur < x->duration[x->w.grabbed-1])
+ dur = x->duration[x->w.grabbed-1] + 1.0;
+ if (dur > x->duration[x->w.grabbed+1])
+ dur = x->duration[x->w.grabbed+1] - 0.2;
+
+ x->duration[x->w.grabbed] = dur;
+ }
+
+
+ x->finalvalues[x->w.grabbed] = 1.0f - (float)(x->w.pointery - x->x_obj.te_ypix)/(float)x->w.height;
+ if (x->finalvalues[x->w.grabbed] < 0.0)
+ x->finalvalues[x->w.grabbed]= 0.0;
+ else if (x->finalvalues[x->w.grabbed] > 1.0)
+ x->finalvalues[x->w.grabbed]= 1.0;
+
+}
+
+
+void envgen_motion(t_envgen *x, t_floatarg dx, t_floatarg dy)
+{
+ x->w.pointerx+=dx;
+ x->w.pointery+=dy;
+
+ if (!x->resizing)
+ envgen_followpointer(x);
+ else {
+ x->w.width+=dx;
+ x->w.height+=dy;
+ }
+ envgen_update(x,x->w.glist);
+}
+
+void envgen_key(t_envgen *x, t_floatarg f)
+{
+ if (f == 8.0 && x->w.grabbed < x->last_state && x->w.grabbed > 0) {
+ int i;
+
+ for (i=x->w.grabbed;i<=x->last_state;i++) {
+ x->duration[i] = x->duration[i+1];
+ x->finalvalues[i] = x->finalvalues[i+1];
+ }
+
+ x->last_state--;
+ x->w.grabbed--;
+ envgen_update(x,x->w.glist);
+ }
+}
+
+
+
+void envgen_click(t_envgen *x,
+ t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
+ t_floatarg alt)
+{
+ /* check if user wants to resize */
+ float wxpos = x->x_obj.te_xpix;
+ float wypos = (int) (x->x_obj.te_ypix + x->w.height);
+
+ x->w.grabbed = envgen_next_doodle(x,xpos,ypos);
+#if (PD_VERSION_MINOR > 31)
+ glist_grab(x->w.glist, &x->x_obj.te_g, envgen_motion, envgen_key, xpos, ypos);
+#else
+ glist_grab(x->w.glist, &x->x_obj.te_g, xpos, ypos);
+#endif
+ x->resizing = 0;
+ if ((xpos > wxpos + x->w.width - 3) &&
+ (fabs(ypos -2 - wypos) < 3.)) {
+ x->resizing = 1;
+ return;
+ }
+
+ x->w.pointerx = xpos;
+ x->w.pointery = ypos;
+ envgen_followpointer(x);
+ envgen_update(x,x->w.glist);
+}
+
+
+#if (PD_VERSION_MINOR > 31)
+static int envgen_newclick(t_gobj *z, struct _glist *glist,
+ int xpix, int ypix, int shift, int alt, int dbl, int doit)
+{
+ if (doit)
+ envgen_click((t_envgen *)z, (t_floatarg)xpix, (t_floatarg)ypix,
+ (t_floatarg)shift, 0, (t_floatarg)alt);
+ return (1);
+}
+#endif
+
+
+
+t_widgetbehavior envgen_widgetbehavior;
+
+void envgen_setwidget()
+{
+ envgen_widgetbehavior.w_getrectfn = envgen_getrect;
+ envgen_widgetbehavior.w_displacefn = envgen_displace;
+ envgen_widgetbehavior.w_selectfn = envgen_select;
+ envgen_widgetbehavior.w_activatefn = envgen_activate;
+ envgen_widgetbehavior.w_deletefn = envgen_delete;
+ envgen_widgetbehavior.w_visfn = envgen_vis;
+#if (PD_VERSION_MINOR > 31)
+ envgen_widgetbehavior.w_clickfn = envgen_newclick;
+ envgen_widgetbehavior.w_propertiesfn = NULL;
+#endif
+ envgen_widgetbehavior.w_savefn = envgen_save;
+
+}
+