diff options
-rw-r--r-- | Makefile.common | 4 | ||||
-rw-r--r-- | ViCious/cyclone/sources | 5 | ||||
-rw-r--r-- | shared/common/props.c | 98 | ||||
-rw-r--r-- | shared/common/props.h | 2 | ||||
-rw-r--r-- | shared/getridof.baddeps | 16 | ||||
-rw-r--r-- | shared/toxy/scriptlet.c | 19 | ||||
-rw-r--r-- | shared/toxy/scriptlet.h | 2 | ||||
-rw-r--r-- | test/toxy/button-test.pd | 16 | ||||
-rw-r--r-- | test/toxy/default.wid | 48 | ||||
-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 |
13 files changed, 344 insertions, 145 deletions
diff --git a/Makefile.common b/Makefile.common index 8c13072..e26bbac 100644 --- a/Makefile.common +++ b/Makefile.common @@ -64,7 +64,8 @@ TYPES_EXTERNS = \ $(patsubst %.c,%$($1_TILDE).$(X_SUFFIX),$(call TYPES_NAMES,$1)) SOURCES = $(CX_SOURCES) $(AX_SOURCES) $(LX_SOURCES) $(OTHER_SOURCES) \ - $(foreach type,$(TYPES),$($(type)_SOURCES)) + $(foreach type,$(TYPES),$($(type)_SOURCES)) \ + $(foreach type,$(TYPES),$($(type)_PRIVATEOBJECTS:.o=.c)) INCLUDES = -I. -I$(PD_DIR) -I$(SHARED_DIR) @@ -202,6 +203,7 @@ clean: emptydeps cleanall: clean # remove default target externs -rm -f $(EXTERNS) + $(SUBDIRS) # added by Hans-Christoph Steiner <hans@eds.org> to remove # files created when making MacOS X packages -rm -Rf ../installroot diff --git a/ViCious/cyclone/sources b/ViCious/cyclone/sources index bff4e74..1f9f88d 100644 --- a/ViCious/cyclone/sources +++ b/ViCious/cyclone/sources @@ -1,7 +1,6 @@ LIB_CYCLONE = \
shadow\cyclone.c \
shadow\nettles.c \
- shadow\dummies.c \
shared\common\loud.c \
shared\common\grow.c \
shared\common\binport.c \
@@ -204,3 +203,7 @@ ALL_SICKLES = \ sickle\vectral.c \
sickle\wave.c \
sickle\zerox.c
+
+LIB_DUMMIES = \
+ shadow\dummies.c \
+ shared\common\loud.c
diff --git a/shared/common/props.c b/shared/common/props.c index 6b6181a..6079308 100644 --- a/shared/common/props.c +++ b/shared/common/props.c @@ -13,6 +13,7 @@ #define PROPS_MAXOTHERS 32 enum { PROPS_NONE = 0, PROPS_THIS, PROPS_OTHER }; +enum { PROPS_SINGLEMODE = 0, PROPS_MULTIMODE }; typedef struct _propelem { @@ -41,8 +42,8 @@ struct _props }; /* Dictionary of properties, p_dict, meant to be nothing more, but an - optimalization detail, is handled implicitly, through its owning t_props. - This optimalization has to be enabled by passing a nonzero 'resolver' + optimization detail, is handled implicitly, through its owning t_props. + This optimization has to be enabled by passing a nonzero 'resolver' argument to props_new(). Since p_dict stores resolved strings, it is a secondary, `shallow' storage, which has to be synced to its master, p_buffer of atoms. @@ -109,18 +110,6 @@ static void props_dictadd(t_props *pp, t_symbol *s, int ac, t_atom *av) } } -static int props_atstart(t_props *pp, char *buf) -{ - if (*buf == pp->p_thisescape) - { - char c = buf[1]; - if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') - || (pp->p_thisinitial && strchr(pp->p_thisinitial, c))) - return (PROPS_THIS); - } - return (PROPS_NONE); -} - static char *props_otherinitial(t_props *pp, char c) { t_props *pp1 = pp->p_otherprops; @@ -135,7 +124,7 @@ static char *props_otherinitial(t_props *pp, char c) return (0); } -static int props_atnext(t_props *pp, char *buf) +static int props_atstart(t_props *pp, int mode, char *buf) { char *otherinitial; if (*buf == pp->p_thisescape) @@ -145,7 +134,8 @@ static int props_atnext(t_props *pp, char *buf) || (pp->p_thisinitial && strchr(pp->p_thisinitial, c))) return (PROPS_THIS); } - else if (*pp->p_otherescapes && strchr(pp->p_otherescapes, *buf)) + else if (mode == PROPS_MULTIMODE && + *pp->p_otherescapes && strchr(pp->p_otherescapes, *buf)) { char c = buf[1]; if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') @@ -158,13 +148,14 @@ static int props_atnext(t_props *pp, char *buf) /* Search for a property, replace its value if found, otherwise add. Assuming s is valid. Returning nafter - nbefore. */ -static int props_update(t_props *pp, t_symbol *s, int ac, t_atom *av, int doit) +static int props_update(t_props *pp, int mode, + t_symbol *s, int ac, t_atom *av, int doit) { int nadd, ndiff, ibeg, iend = 0; t_atom *ap; for (nadd = 0, ap = av; nadd < ac; nadd++, ap++) if (ap->a_type == A_SYMBOL - && props_atnext(pp, ap->a_w.w_symbol->s_name)) + && props_atstart(pp, mode, ap->a_w.w_symbol->s_name)) break; if (!nadd) { @@ -179,7 +170,8 @@ static int props_update(t_props *pp, t_symbol *s, int ac, t_atom *av, int doit) { for (iend = ibeg + 1, ap++; iend < pp->p_natoms; iend++, ap++) if (ap->a_type == A_SYMBOL - && props_atnext(pp, ap->a_w.w_symbol->s_name)) + && props_atstart(pp, PROPS_SINGLEMODE, + ap->a_w.w_symbol->s_name)) break; break; } @@ -228,23 +220,43 @@ static int props_update(t_props *pp, t_symbol *s, int ac, t_atom *av, int doit) return (ndiff); } -/* If there is an empty property, do not parse beyond. - Return the offending switch, if any. */ -t_symbol *props_add(t_props *pp, t_symbol *s, int ac, t_atom *av) +/* If in a single mode, ignore `other' properties (their switches are parsed + through as values). If there is an empty property, which is not to be + ignored, do not parse beyond. Return an offending switch, if any. */ +t_symbol *props_add(t_props *pp, int single, t_symbol *s, int ac, t_atom *av) { t_symbol *empty = 0; t_atom *av1, *ap; + int mode = (single ? PROPS_SINGLEMODE : PROPS_MULTIMODE); int ac1, i, ngrown = 0; - if (s && props_atstart(pp, s->s_name)) - ngrown += props_update(pp, s, ac, av, 0); + if (!s || !props_atstart(pp, PROPS_SINGLEMODE, s->s_name)) + { + s = 0; + while (ac) + { + s = (av->a_type == A_SYMBOL ? av->a_w.w_symbol : 0); + ac--; av++; + if (s && props_atstart(pp, PROPS_SINGLEMODE, s->s_name)) + break; + s = 0; + } + } + if (!s || !ac) + { + empty = s; + goto done; + } + ngrown += props_update(pp, mode, s, ac, av, 0); if (pp->p_badupdate) empty = s; else for (i = 0, ap = av; i < ac; i++, ap++) { if (ap->a_type == A_SYMBOL - && props_atstart(pp, ap->a_w.w_symbol->s_name)) + && props_atstart(pp, PROPS_SINGLEMODE, + ap->a_w.w_symbol->s_name)) { - ngrown += props_update(pp, ap->a_w.w_symbol, ac - i - 1, ap + 1, 0); + ngrown += props_update(pp, mode, ap->a_w.w_symbol, + ac - i - 1, ap + 1, 0); if (pp->p_badupdate) { empty = ap->a_w.w_symbol; @@ -263,24 +275,17 @@ t_symbol *props_add(t_props *pp, t_symbol *s, int ac, t_atom *av) if (nrequested != ngrown) goto done; } - ac1 = (s ? ac + 1 : ac); - if (!(av1 = getbytes(ac1 * sizeof(*av1)))) - goto done; - ap = av1; - if (s) - { - SETSYMBOL(ap, s); - ap++; - } - while (ac--) *ap++ = *av++; - ac = ac1; - av = av1; - for (i = 0, ap = av; i < ac; i++, ap++) + props_update(pp, mode, s, ac, av, 1); + if (pp->p_badupdate) + empty = s; + else for (i = 0, ap = av; i < ac; i++, ap++) { if (ap->a_type == A_SYMBOL - && props_atstart(pp, ap->a_w.w_symbol->s_name)) + && props_atstart(pp, PROPS_SINGLEMODE, + ap->a_w.w_symbol->s_name)) { - props_update(pp, ap->a_w.w_symbol, ac - i - 1, ap + 1, 1); + props_update(pp, mode, ap->a_w.w_symbol, + ac - i - 1, ap + 1, 1); if (pp->p_badupdate) { empty = ap->a_w.w_symbol; @@ -288,7 +293,6 @@ t_symbol *props_add(t_props *pp, t_symbol *s, int ac, t_atom *av) } } } - freebytes(av1, ac1 * sizeof(*av1)); done: return (empty); } @@ -328,11 +332,12 @@ void props_clone(t_props *to, t_props *from) while (ibeg < from->p_natoms) { if (ap->a_type == A_SYMBOL && - props_atstart(from, ap->a_w.w_symbol->s_name)) + props_atstart(from, PROPS_SINGLEMODE, ap->a_w.w_symbol->s_name)) { for (iend = ibeg + 1, ap++; iend < from->p_natoms; iend++, ap++) if (ap->a_type == A_SYMBOL - && props_atnext(from, ap->a_w.w_symbol->s_name)) + && props_atstart(from, PROPS_MULTIMODE, + ap->a_w.w_symbol->s_name)) break; props_dictadd(to, abeg->a_w.w_symbol, iend - ibeg - 1, abeg + 1); @@ -397,7 +402,7 @@ t_atom *props_getone(t_props *pp, t_symbol *s, int *npp) { int ibeg, iend = 0; t_atom *ap; - if (!(s && props_atstart(pp, s->s_name))) + if (!(s && props_atstart(pp, PROPS_SINGLEMODE, s->s_name))) return (0); for (ibeg = 0, ap = pp->p_buffer; ibeg < pp->p_natoms; ibeg++, ap++) { @@ -405,7 +410,8 @@ t_atom *props_getone(t_props *pp, t_symbol *s, int *npp) { for (iend = ibeg + 1, ap++; iend < pp->p_natoms; iend++, ap++) if (ap->a_type == A_SYMBOL - && props_atnext(pp, ap->a_w.w_symbol->s_name)) + && props_atstart(pp, PROPS_MULTIMODE, + ap->a_w.w_symbol->s_name)) break; break; } diff --git a/shared/common/props.h b/shared/common/props.h index 0eef345..8e3add6 100644 --- a/shared/common/props.h +++ b/shared/common/props.h @@ -10,7 +10,7 @@ EXTERN_STRUCT _props; typedef char *(*t_propsresolver)(t_pd *, int, t_atom *); -t_symbol *props_add(t_props *pp, t_symbol *s, int ac, t_atom *av); +t_symbol *props_add(t_props *pp, int single, t_symbol *s, int ac, t_atom *av); int props_remove(t_props *pp, t_symbol *s); void props_clone(t_props *to, t_props *from); char *props_getvalue(t_props *pp, char *key); diff --git a/shared/getridof.baddeps b/shared/getridof.baddeps new file mode 100644 index 0000000..37c56d5 --- /dev/null +++ b/shared/getridof.baddeps @@ -0,0 +1,16 @@ +This is the list of all dependencies among miXed/shared objects. +Some are inevitable, but others can, and should be removed. + +unstable/fringe -> unstable/forky +toxy/scriptlet -> common/loud, common/grow, common/props +sickle/sic -> common/loud +sickle/arsic -> common/loud, common/vefl, sickle/sic, unstable/fragile +hammer/file -> unstable/forky +common/hyphen -> common/dict +common/props -> common/grow +common/vefl -> common/loud, unstable/fragile +common/port -> common/loud, common/grow, common/binport, + unstable/forky, unstable/fragile, unstable/fringe +common/sofi -> common/bifi +common/mifi -> common/bifi common/sq +common/mfbb -> common/bifi, common/mifi, common/sq, common/squeal diff --git a/shared/toxy/scriptlet.c b/shared/toxy/scriptlet.c index 2592cee..e2f9883 100644 --- a/shared/toxy/scriptlet.c +++ b/shared/toxy/scriptlet.c @@ -277,6 +277,11 @@ static char *scriptlet_dedot(t_scriptlet *sp, char *ibuf, char *obuf, return (len ? ibuf + len : 0); } +int scriptlet_isempty(t_scriptlet *sp) +{ + return (!(sp->s_tail > sp->s_head && *sp->s_head)); +} + void scriptlet_reset(t_scriptlet *sp) { sp->s_cvstate = SCRIPTLET_CVUNKNOWN; @@ -395,6 +400,20 @@ void scriptlet_qpush(t_scriptlet *sp) } } +/* Non-expanding -- LATER think if this is likely to cause any confusion. + Especially, consider the widget_vis() vs. widget_update() case. */ +void scriptlet_vpush(t_scriptlet *sp, char *varname) +{ + if (scriptlet_ready(sp)) + { + char *tail = sp->s_tail; + strcpy(tail, "}\n"); + sys_vgui("set ::toxy::%s { ", varname); + sys_gui(sp->s_head); + *tail = 0; + } +} + int scriptlet_evaluate(t_scriptlet *insp, t_scriptlet *outsp, int visedonly, int ac, t_atom *av, t_props *argprops) { diff --git a/shared/toxy/scriptlet.h b/shared/toxy/scriptlet.h index 4b057b9..336d729 100644 --- a/shared/toxy/scriptlet.h +++ b/shared/toxy/scriptlet.h @@ -14,6 +14,7 @@ EXTERN_STRUCT _scriptlet; typedef t_canvas *(*t_scriptlet_cvfn)(t_pd *); typedef t_scriptlet *(*t_scriptlet_cmntfn)(t_pd *, char *, char, char *); +int scriptlet_isempty(t_scriptlet *sp); void scriptlet_reset(t_scriptlet *sp); void scriptlet_prealloc(t_scriptlet *sp, int sz, int mayshrink); int scriptlet_add(t_scriptlet *sp, @@ -25,6 +26,7 @@ int scriptlet_addfloat(t_scriptlet *sp, t_float f); void scriptlet_setseparator(t_scriptlet *sp, char c); void scriptlet_push(t_scriptlet *sp); void scriptlet_qpush(t_scriptlet *sp); +void scriptlet_vpush(t_scriptlet *sp, char *varname); int scriptlet_evaluate(t_scriptlet *insp, t_scriptlet *outsp, int visedonly, int ac, t_atom *av, t_props *argprops); char *scriptlet_nextword(char *buf); diff --git a/test/toxy/button-test.pd b/test/toxy/button-test.pd index 1f553dd..1fff19f 100644 --- a/test/toxy/button-test.pd +++ b/test/toxy/button-test.pd @@ -12,14 +12,14 @@ red -command .<.>; #X msg 21 21 -bg red -text red; #X msg 34 47 -bg green -text green; #X msg 56 101 -bg gray -text ""; -#X msg 62 132 -activebackground \$1; #X msg 250 74 query tk_chooseColor; #X obj 250 101 tot .; #X msg 166 187 -command .<:t1 bang.>; -#X msg 90 213 -command .(set c [tk_chooseColor] .: eval .<| "-bg" $c -"-text" $c.>.); #X msg 68 186 -width \$1; #X floatatom 68 162 5 0 0 0 - - -; +#X msg 62 132 set -activebackground \$1; +#X msg 90 213 -command .(set c [tk_chooseColor] .: eval .<| set "-bg" +$c "-text" $c.>.); #X connect 0 0 3 0; #X connect 1 0 0 0; #X connect 2 0 0 0; @@ -28,10 +28,10 @@ red -command .<.>; #X connect 7 0 0 0; #X connect 8 0 0 0; #X connect 9 0 0 0; -#X connect 10 0 0 0; -#X connect 11 0 12 0; -#X connect 12 0 10 0; +#X connect 10 0 11 0; +#X connect 11 0 15 0; +#X connect 12 0 0 0; #X connect 13 0 0 0; -#X connect 14 0 0 0; +#X connect 14 0 13 0; #X connect 15 0 0 0; -#X connect 16 0 15 0; +#X connect 16 0 0 0; diff --git a/test/toxy/default.wid b/test/toxy/default.wid index e9a20a1..abe9a5a 100644 --- a/test/toxy/default.wid +++ b/test/toxy/default.wid @@ -3,6 +3,54 @@ # LATER ask for adding something of the sort to pd.tk: bind Canvas <1> {+focus %W} +proc ::toxy::itemleave {path target varname} { + if {[catch {$path get} ::toxy::itemvalue] == 0} { + set $varname $::toxy::itemvalue +# LATER try sending only if changed + pd $target.rp _value $::toxy::itemvalue \; + } +} + +proc ::toxy::itemvis {tkclass path target name varname cvpath px py} { + set ::toxy::itemfailure [catch {$tkclass $path} ::toxy::itemerrmess] + if {$::toxy::itemfailure} { + pd $target.rp _failure $::toxy::itemerrmess \; + } else { + + if {[info exists ::toxy::itemoptions]} { + catch {eval $path config $::toxy::itemoptions} + unset ::toxy::itemoptions + } + + $cvpath create window $px $py \ + -anchor nw -window $path -tags [concat toxy$name $target] + + if {[info exists ::toxy::masterinits]} { + catch {eval $::toxy::masterinits} + unset ::toxy::masterinits + } + if {[info exists ::toxy::typeinits]} { + catch {eval $::toxy::typeinits} + unset ::toxy::typeinits + } + if {[info exists ::toxy::iteminits]} { + catch {eval $::toxy::iteminits} + unset ::toxy::iteminits + } + + pd $target.rp _config $target.rp [$path cget -bg] \ + [winfo reqwidth $path] [winfo reqheight $path] \ + [catch {$path config -state normal}]\; + +# LATER think where to plug this in + bind $path <Leave> [concat ::toxy::itemleave $path $target $varname] + if {[info exists $varname]} { + catch {eval $path set $$varname} + unset $varname + } + } +} + proc ::toxy::popup {path target remote entries args} { eval {menu $path.pop} $args set i 1 @@ -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'\ |