aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.common4
-rw-r--r--ViCious/cyclone/sources5
-rw-r--r--shared/common/props.c98
-rw-r--r--shared/common/props.h2
-rw-r--r--shared/getridof.baddeps16
-rw-r--r--shared/toxy/scriptlet.c19
-rw-r--r--shared/toxy/scriptlet.h2
-rw-r--r--test/toxy/button-test.pd16
-rw-r--r--test/toxy/default.wid48
-rw-r--r--toxy/tot.c43
-rw-r--r--toxy/toxy-shared.include1
-rw-r--r--toxy/widget.c229
-rw-r--r--toxy/widgettype.c6
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
diff --git a/toxy/tot.c b/toxy/tot.c
index eced2b2..0bddfc3 100644
--- a/toxy/tot.c
+++ b/toxy/tot.c
@@ -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'\