diff options
Diffstat (limited to 'toxy')
-rw-r--r-- | toxy/tot.c | 43 | ||||
-rw-r--r-- | toxy/toxy-shared.include | 1 | ||||
-rw-r--r-- | toxy/widget.c | 229 | ||||
-rw-r--r-- | toxy/widgettype.c | 6 |
4 files changed, 191 insertions, 88 deletions
@@ -48,6 +48,8 @@ typedef struct _totspy t_canvas *ts_cv; t_symbol *ts_target; t_symbol *ts_qsym; + int ts_gotmotion; + t_atom ts_lastmotion[3]; double ts_lasttime; t_symbol *ts_selector; t_atom ts_outbuf[TOTSPY_MAXSIZE]; @@ -59,8 +61,9 @@ static t_class *totspy_class; static t_class *totsink_class; static t_class *tot_guiconnect_class = 0; -static t_symbol *tot_ps_qpush; -static t_symbol *tot_ps_query; +static t_symbol *totps_motion; +static t_symbol *totps_qpush; +static t_symbol *totps_query; static t_canvas *tot_getcanvas(t_tot *x, int complain) { @@ -144,7 +147,7 @@ static void tot_push(t_tot *x, t_symbol *s, int ac, t_atom *av) { if (scriptlet_evaluate(x->x_persistent, x->x_transient, 1, ac, av, 0)) { - if (s == tot_ps_qpush) + if (s == totps_qpush) scriptlet_qpush(x->x_transient); else scriptlet_push(x->x_transient); @@ -158,7 +161,7 @@ static void tot_tot(t_tot *x, t_symbol *s, int ac, t_atom *av) t_scriptlet *sp = x->x_transient; scriptlet_reset(sp); scriptlet_add(sp, 1, 1, ac, av); - if (s == tot_ps_query) + if (s == totps_query) scriptlet_qpush(sp); else scriptlet_push(sp); @@ -379,8 +382,32 @@ static void tot_capture(t_tot *x, t_symbol *s, t_floatarg f) else ts->ts_on = 0; } +/* this is needed to overcome glist_getnextxy()-related troubles */ +static void tot_lastmotion(t_tot *x, t_symbol *s) +{ + t_totspy *ts = x->x_spy; + if (ts->ts_gotmotion) + { + if (s == &s_) + s = ts->ts_target; + if (s && s->s_thing) + typedmess(s->s_thing, totps_motion, 3, ts->ts_lastmotion); + } +} + static void totspy_anything(t_totspy *ts, t_symbol *s, int ac, t_atom *av) { + if (s == totps_motion) + { + if (ac == 3) + { + ts->ts_lastmotion[0] = av[0]; + ts->ts_lastmotion[1] = av[1]; + ts->ts_lastmotion[2] = av[2]; + ts->ts_gotmotion = 1; + } + else bug("totspy_anything"); + } if (ts->ts_on) { if (ts->ts_qsym) @@ -454,6 +481,7 @@ static void *tot_new(t_symbol *s1, t_symbol *s2) x->x_spy->ts_cv = 0; x->x_spy->ts_target = 0; x->x_spy->ts_qsym = 0; + x->x_spy->ts_gotmotion = 0; x->x_spy->ts_out3 = outlet_new((t_object *)x, &s_anything); x->x_out4 = outlet_new((t_object *)x, &s_bang); if (s2 && s2 != &s_) @@ -475,8 +503,9 @@ void tot_setup(void) { post("beware! this is tot %s, %s %s build...", TOXY_VERSION, loud_ordinal(TOXY_BUILD), TOXY_RELEASE); - tot_ps_qpush = gensym("qpush"); - tot_ps_query = gensym("query"); + totps_motion = gensym("motion"); + totps_qpush = gensym("qpush"); + totps_query = gensym("query"); tot_class = class_new(gensym("tot"), (t_newmethod)tot_new, (t_method)tot_free, @@ -507,6 +536,8 @@ void tot_setup(void) gensym("attach"), 0); class_addmethod(tot_class, (t_method)tot_capture, gensym("capture"), A_FLOAT, A_DEFSYM, 0); + class_addmethod(tot_class, (t_method)tot_lastmotion, + gensym("lastmotion"), A_DEFSYM, 0); class_addmethod(tot_class, (t_method)tot__reply, gensym("_rp"), A_GIMME, 0); class_addmethod(tot_class, (t_method)tot__callback, diff --git a/toxy/toxy-shared.include b/toxy/toxy-shared.include index e754469..e831217 100644 --- a/toxy/toxy-shared.include +++ b/toxy/toxy-shared.include @@ -1,3 +1,4 @@ +shared/shared.h shared/common/loud.c shared/common/loud.h shared/common/grow.c diff --git a/toxy/widget.c b/toxy/widget.c index aff5e32..253b649 100644 --- a/toxy/widget.c +++ b/toxy/widget.c @@ -3,7 +3,6 @@ * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* LATER think about reloading method for .wid files */ -/* FIXME sink-binding */ #include <stdio.h> #include <string.h> @@ -49,6 +48,8 @@ typedef struct _widget t_symbol *x_cbtarget; /* same, mangled (a target, and a tag) */ t_symbol *x_rptarget; /* same, further mangled */ t_symbol *x_cvpathname; /* see widget_getcvpathname() */ + t_symbol *x_cvtarget; /* for gui commands to be (re)sent to */ + t_symbol *x_varname; /* tcl variable holding our data */ t_props *x_options; /* instance options */ t_props *x_handlers; /* instance handlers */ t_props *x_arguments; /* instance arguments */ @@ -64,6 +65,7 @@ typedef struct _widget int x_update; /* see widget_update() */ int x_selected; int x_disabled; + int x_vised; t_clock *x_transclock; t_towentry *x_towlist; } t_widget; @@ -88,6 +90,12 @@ static t_class *tow_class; because a destination glist is searched instead in tow_attach(). */ static t_tow *towlist = 0; +static t_symbol *widgetps_mouse; +static t_symbol *widgetps_motion; +static t_symbol *widgetps_atbang; +static t_symbol *widgetps_atfloat; +static t_symbol *widgetps_atsymbol; + static char *widget_propsresolver(t_pd *z, int ac, t_atom *av) { t_widget *x = (t_widget *)z; @@ -239,7 +247,7 @@ static void widget_delete(t_gobj *z, t_glist *glist) canvas_deletelinesfor(glist, (t_text *)z); } -static void widget_pushoptions(t_widget *x) +static void widget_pushoptions(t_widget *x, int doit) { char *mypathname = widget_getmypathname(x, x->x_glist)->s_name; if (scriptlet_evaluate(x->x_optscript, x->x_transient, 0, 0, 0, 0)) @@ -249,38 +257,37 @@ static void widget_pushoptions(t_widget *x) char *dp = scriptlet_getcontents(x->x_transient, &sz); post("vis: \"%s\"", dp); #endif - sys_vgui("%s config ", mypathname); - scriptlet_push(x->x_transient); - } - else - { - /* LATER if scriptlet not empty: bug("widget_pushoptions"); */ + if (doit) + { + sys_vgui("%s config ", mypathname); + scriptlet_push(x->x_transient); + } + else scriptlet_vpush(x->x_transient, "itemoptions"); } + else if (!scriptlet_isempty(x->x_optscript)) + bug("widget_pushoptions"); } static void widget_pushinits(t_widget *x) { if (masterwidget_evaluate(x->x_transient, 0, 0, 0, x->x_arguments)) - scriptlet_push(x->x_transient); + scriptlet_vpush(x->x_transient, "masterinits"); else bug("widget_pushinits (master)"); if (widgettype_isdefined(x->x_typedef)) { + int sz; if (widgettype_evaluate(x->x_typedef, x->x_transient, 0, 0, 0, x->x_arguments)) - scriptlet_push(x->x_transient); - else - { - /* LATER if scriptlet not empty: bug("widget_pushinits (type)"); */ - } + scriptlet_vpush(x->x_transient, "typeinits"); + else if (*widgettype_getcontents(x->x_typedef, &sz) && sz > 0) + bug("widget_pushinits (type)"); } if (scriptlet_evaluate(x->x_iniscript, x->x_transient, 0, 0, 0, x->x_arguments)) - scriptlet_push(x->x_transient); - else - { - /* LATER if scriptlet not empty: bug("widget_pushinits (instance)"); */ - } + scriptlet_vpush(x->x_transient, "iteminits"); + else if (!scriptlet_isempty(x->x_iniscript)) + bug("widget_pushinits (instance)"); } static void widget_vis(t_gobj *z, t_glist *glist, int vis) @@ -297,26 +304,13 @@ static void widget_vis(t_gobj *z, t_glist *glist, int vis) #ifndef PD_MINOR_VERSION rtext_new(glist, t, glist->gl_editor->e_rtext, 0); #endif - sys_vgui("set ::toxy::itempath %s; set ::toxy::itemtarget %s\n\ - set ::toxy::itemfailure [catch {%s %s}]\n\ - if {$::toxy::itemfailure} {pd %s _failure\\;}\n", - mypathname, x->x_rptarget->s_name, - x->x_tkclass->s_name, mypathname, - x->x_rptarget->s_name); - widget_pushoptions(x); - sys_vgui("if {$::toxy::itemfailure == 0}\ - {%s create window %g %g\ - -anchor nw -window %s -tags {toxy%s %s}}\n", - cvpathname, px1, py1, mypathname, - x->x_name->s_name, x->x_cbtarget->s_name); + widget_pushoptions(x, 0); widget_pushinits(x); - sys_vgui("if {$::toxy::itemfailure == 0}\ - {pd %s _config %s [%s cget -bg]\ - [winfo reqwidth %s] [winfo reqheight %s]\ - [catch {%s config -state normal}]\\;}\n", - x->x_rptarget->s_name, x->x_rptarget->s_name, - mypathname, mypathname, mypathname, mypathname); - sys_gui("unset ::toxy::itempath; unset ::toxy::itemtarget\n"); + sys_vgui("::toxy::itemvis %s %s %s %s %s %s %g %g\n", + x->x_tkclass->s_name, mypathname, + x->x_cbtarget->s_name, x->x_name->s_name, + x->x_varname->s_name, cvpathname, px1, py1); + x->x_vised = 1; } else { @@ -324,7 +318,11 @@ static void widget_vis(t_gobj *z, t_glist *glist, int vis) t_rtext *rt = glist_findrtext(glist, t); if (rt) rtext_free(rt); #endif - sys_vgui("destroy %s\n", mypathname); + if (x->x_vised) + { + sys_vgui("destroy %s\n", mypathname); + x->x_vised = 0; + } } } @@ -424,19 +422,19 @@ static void widget_update(t_widget *x) widget_vis((t_gobj *)x, x->x_glist, 0); widget_vis((t_gobj *)x, x->x_glist, 1); } - else widget_pushoptions(x); + else widget_pushoptions(x, 1); x->x_update = WIDGET_NOUPDATE; } /* LATER cache handlers */ } -static t_symbol *widget_addprops(t_widget *x, t_props *op, +static t_symbol *widget_addprops(t_widget *x, t_props *op, int single, t_symbol *s, int ac, t_atom *av) { if (op) { t_symbol *empty; - empty = props_add(op, s, ac, av); + empty = props_add(op, single, s, ac, av); if (empty) loud_error((t_pd *)x, "no value given for %s '%s'", props_getname(op), empty->s_name); @@ -453,9 +451,9 @@ static t_symbol *widget_addprops(t_widget *x, t_props *op, static t_symbol *widget_addmessage(t_widget *x, t_symbol *s, int ac, t_atom *av) { t_symbol *empty; - if (!(empty = widget_addprops(x, x->x_options, s, ac, av)) && - !(empty = widget_addprops(x, x->x_handlers, s, ac, av))) - empty = widget_addprops(x, x->x_arguments, s, ac, av); + if (!(empty = widget_addprops(x, x->x_options, 0, s, ac, av)) && + !(empty = widget_addprops(x, x->x_handlers, 0, s, ac, av))) + empty = widget_addprops(x, x->x_arguments, 0, s, ac, av); return (empty); } @@ -503,9 +501,9 @@ static void widget_bang(t_widget *x) { int ac; t_atom *av; - t_symbol *sel = gensym("@bang"); - if ((av = props_getone(x->x_handlers, sel, &ac)) || - (av = props_getone(widgettype_gethandlers(x->x_typedef), sel, &ac))) + if ((av = props_getone(x->x_handlers, widgetps_atbang, &ac)) || + (av = props_getone(widgettype_gethandlers(x->x_typedef), + widgetps_atbang, &ac))) { if (ac > 1) { @@ -521,9 +519,9 @@ static void widget_float(t_widget *x, t_float f) { int ac; t_atom *av; - t_symbol *sel = gensym("@float"); - if ((av = props_getone(x->x_handlers, sel, &ac)) || - (av = props_getone(widgettype_gethandlers(x->x_typedef), sel, &ac))) + if ((av = props_getone(x->x_handlers, widgetps_atfloat, &ac)) || + (av = props_getone(widgettype_gethandlers(x->x_typedef), + widgetps_atfloat, &ac))) { if (ac > 1) { @@ -543,9 +541,9 @@ static void widget_symbol(t_widget *x, t_symbol *s) { int ac; t_atom *av; - t_symbol *sel = gensym("@symbol"); - if ((av = props_getone(x->x_handlers, sel, &ac)) || - (av = props_getone(widgettype_gethandlers(x->x_typedef), sel, &ac))) + if ((av = props_getone(x->x_handlers, widgetps_atsymbol, &ac)) || + (av = props_getone(widgettype_gethandlers(x->x_typedef), + widgetps_atsymbol, &ac))) { if (ac > 1) { @@ -560,6 +558,28 @@ static void widget_symbol(t_widget *x, t_symbol *s) } } +static void widget_set(t_widget *x, t_symbol *s, int ac, t_atom *av) +{ + t_symbol *prp; + if (ac && av->a_type == A_SYMBOL && (prp = av->a_w.w_symbol)) + { + t_symbol *empty = 0; + x->x_update = WIDGET_RECONFIG; + ac--; av++; + if (*prp->s_name == '-') + empty = widget_addprops(x, x->x_options, 1, prp, ac, av); + else if (*prp->s_name == '@') + empty = widget_addprops(x, x->x_handlers, 1, prp, ac, av); + else if (*prp->s_name == '#') + empty = widget_addprops(x, x->x_arguments, 1, prp, ac, av); + if (empty) + loud_errand((t_pd *)x, + "(use 'remove %s' if that is what you want).", + empty->s_name); + } + else loud_messarg((t_pd *)x, s); +} + static void widget_remove(t_widget *x, t_symbol *s) { if (s) @@ -608,10 +628,13 @@ static void widget_refresh(t_widget *x) widget_update(x); } -static void widget__failure(t_widget *x) +static void widget__failure(t_widget *x, t_symbol *s, int ac, t_atom *av) { - /* LATER pass error message from gui, and report here */ + startpost("tcl error:"); + postatom(ac, av); + endpost(); loud_error((t_pd *)x, "creation failure"); + x->x_vised = 0; widget_transedit(x); } @@ -619,7 +642,8 @@ static void widget__config(t_widget *x, t_symbol *target, t_symbol *bg, t_floatarg fw, t_floatarg fh, t_floatarg fst) { #ifdef WIDGET_DEBUG - post("config %d \"%s\" %g %g", bg->s_name, fw, fh); + post("config %x %s \"%s\" %g %g", + (int)x, target->s_name, bg->s_name, fw, fh); #endif x->x_width = (int)fw; x->x_height = (int)fh; @@ -628,6 +652,16 @@ static void widget__config(t_widget *x, t_symbol *target, t_symbol *bg, canvas_fixlinesfor(glist_getcanvas(x->x_glist), (t_text *)x); /* FIXME */ } +static void widget__value(t_widget *x, t_symbol *s, int ac, t_atom *av) +{ +#ifdef WIDGET_DEBUG + startpost("value:"); + postatom(ac, av); + endpost(); +#endif + /* FIXME */ +} + static void widget__callback(t_widget *x, t_symbol *s, int ac, t_atom *av) { if (ac == 1) @@ -677,28 +711,43 @@ static void widget__inout(t_widget *x, t_floatarg f) static void widget__click(t_widget *x, t_floatarg fx, t_floatarg fy, t_floatarg fb, t_floatarg fm) { - t_text *t = (t_text *)x; - t_atom at[4]; - fx += t->te_xpix; - fy += t->te_ypix; - SETFLOAT(&at[0], fx); - SETFLOAT(&at[1], fy); - SETFLOAT(&at[2], fb); - SETFLOAT(&at[3], fm); - typedmess((t_pd *)x->x_glist, gensym("mouse"), 4, at); - widget__inout(x, 1.); + if (x->x_glist->gl_havewindow) /* LATER calculate on-parent coords */ + { + t_text *t = (t_text *)x; + t_atom at[4]; + fx += t->te_xpix; + fy += t->te_ypix; + SETFLOAT(&at[0], fx); + SETFLOAT(&at[1], fy); + SETFLOAT(&at[2], fb); + SETFLOAT(&at[3], fm); + if (x->x_cvtarget->s_thing) + /* LATER rethink */ + typedmess(x->x_cvtarget->s_thing, widgetps_mouse, 4, at); + else + typedmess((t_pd *)x->x_glist, widgetps_mouse, 4, at); + widget__inout(x, 1.); + } } +/* LATER think how to grab the mouse when dragging */ static void widget__motion(t_widget *x, t_floatarg fx, t_floatarg fy) { - t_text *t = (t_text *)x; - t_atom at[3]; - fx += t->te_xpix; - fy += t->te_ypix; - SETFLOAT(&at[0], fx); - SETFLOAT(&at[1], fy); - SETFLOAT(&at[2], 0); - typedmess((t_pd *)x->x_glist, gensym("motion"), 3, at); + if (x->x_glist->gl_havewindow) /* LATER calculate on-parent coords */ + { + t_text *t = (t_text *)x; + t_atom at[3]; + fx += t->te_xpix; + fy += t->te_ypix; + SETFLOAT(&at[0], fx); + SETFLOAT(&at[1], fy); + SETFLOAT(&at[2], 0); + if (x->x_cvtarget->s_thing) + /* LATER rethink */ + typedmess(x->x_cvtarget->s_thing, widgetps_motion, 3, at); + else + typedmess((t_pd *)x->x_glist, widgetps_motion, 3, at); + } } int widget_iswidget(t_gobj *g, t_symbol *type, t_symbol *name) @@ -756,10 +805,18 @@ static void widget_debug(t_widget *x) static void widget_attach(t_widget *x); static void widget_detach(t_widget *x); +/* FIXME for all gui objects use a single sink (with a single clock) */ +static void gui_unbind(t_pd *x, t_symbol *s) +{ + t_guiconnect *gc = guiconnect_new(0, s); + guiconnect_notarget(gc, 1000.); + pd_unbind(x, s); +} + static void widget_free(t_widget *x) { - pd_unbind((t_pd *)x, x->x_cbtarget); - pd_unbind((t_pd *)x, x->x_rptarget); + gui_unbind((t_pd *)x, x->x_cbtarget); + gui_unbind((t_pd *)x, x->x_rptarget); props_freeall(x->x_options); scriptlet_free(x->x_iniscript); scriptlet_free(x->x_optscript); @@ -823,6 +880,10 @@ static void *widget_new(t_symbol *s, int ac, t_atom *av) x->x_glist = canvas_getcurrent(); sprintf(buf, ".x%x.c", (int)x->x_glist); x->x_cvpathname = gensym(buf); + sprintf(buf, ".x%x", (int)x->x_glist); + x->x_cvtarget = gensym(buf); + sprintf(buf, "::toxy::v%x", (int)x); + x->x_varname = gensym(buf); outlet_new((t_object *)x, &s_anything); /* LATER consider estimating these, based on widget class and options */ x->x_width = 50; @@ -835,6 +896,7 @@ static void *widget_new(t_symbol *s, int ac, t_atom *av) x->x_hasstate = 0; x->x_update = WIDGET_NOUPDATE; x->x_disabled = 0; + x->x_vised = 0; widget_attach(x); return (x); } @@ -1086,6 +1148,11 @@ void widget_setup(void) { post("beware! this is widget %s, %s %s build...", TOXY_VERSION, loud_ordinal(TOXY_BUILD), TOXY_RELEASE); + widgetps_mouse = gensym("mouse"); + widgetps_motion = gensym("motion"); + widgetps_atbang = gensym("@bang"); + widgetps_atfloat = gensym("@float"); + widgetps_atsymbol = gensym("@symbol"); widgettype_setup(); widget_class = class_new(gensym("widget"), (t_newmethod)widget_new, @@ -1098,6 +1165,8 @@ void widget_setup(void) class_addfloat(widget_class, widget_float); class_addsymbol(widget_class, widget_symbol); class_addanything(widget_class, widget_anything); + class_addmethod(widget_class, (t_method)widget_set, + gensym("set"), A_GIMME, 0); class_addmethod(widget_class, (t_method)widget_remove, gensym("remove"), A_SYMBOL, 0); class_addmethod(widget_class, (t_method)widget_ini, @@ -1106,11 +1175,13 @@ void widget_setup(void) gensym("tot"), A_GIMME, 0); class_addmethod(widget_class, (t_method)widget_refresh, gensym("refresh"), 0); + class_addmethod(widget_class, (t_method)widget__failure, + gensym("_failure"), A_GIMME, 0); class_addmethod(widget_class, (t_method)widget__config, gensym("_config"), A_SYMBOL, A_SYMBOL, A_FLOAT, A_FLOAT, A_FLOAT, 0); - class_addmethod(widget_class, (t_method)widget__failure, - gensym("_failure"), 0); + class_addmethod(widget_class, (t_method)widget__value, + gensym("_value"), A_GIMME, 0); class_addmethod(widget_class, (t_method)widget__callback, gensym("_cb"), A_GIMME, 0); class_addmethod(widget_class, (t_method)widget__inout, diff --git a/toxy/widgettype.c b/toxy/widgettype.c index 6f26c27..5a5684f 100644 --- a/toxy/widgettype.c +++ b/toxy/widgettype.c @@ -136,11 +136,11 @@ static t_scriptlet *masterwidget_cmnthook(t_pd *z, char *rc, t_atom *av = binbuf_getvec(mw->mw_bb); t_props *pp; if (!(empty = props_add(pp = mw->mw_parsedtype->wt_options, - 0, ac, av)) && + 0, 0, ac, av)) && !(empty = props_add(pp = mw->mw_parsedtype->wt_handlers, - 0, ac, av))) + 0, 0, ac, av))) empty = props_add(pp = mw->mw_parsedtype->wt_arguments, - 0, ac, av); + 0, 0, ac, av); if (empty) loud_warning((t_pd *)mw, "no value given for %s '%s'\ |