diff options
43 files changed, 4664 insertions, 1 deletions
diff --git a/shared/Makefile.dirs b/shared/Makefile.dirs index d9be5aa..5764f41 100644 --- a/shared/Makefile.dirs +++ b/shared/Makefile.dirs @@ -1 +1 @@ -MIXED_DIRS = common hammer sickle toys unstable +MIXED_DIRS = common hammer sickle toxy unstable diff --git a/shared/common/props.c b/shared/common/props.c new file mode 100644 index 0000000..6b6181a --- /dev/null +++ b/shared/common/props.c @@ -0,0 +1,518 @@ +/* Copyright (c) 2003 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#include <string.h> +#include "m_pd.h" +#include "common/grow.h" +#include "common/props.h" + +//#define PROPS_DEBUG + +#define PROPS_INISIZE 32 /* LATER rethink */ +#define PROPS_MAXOTHERS 32 + +enum { PROPS_NONE = 0, PROPS_THIS, PROPS_OTHER }; + +typedef struct _propelem +{ + char *e_key; + char *e_value; + struct _propelem *e_next; +} t_propelem; + +struct _props +{ + char p_thisescape; + char *p_thisinitial; + char *p_name; + int p_size; /* as allocated */ + int p_natoms; /* as used */ + t_atom *p_buffer; + t_atom p_bufini[PROPS_INISIZE]; + t_pd *p_owner; + t_propsresolver p_resolver; + t_propelem *p_dict; + t_propelem *p_nextelem; + int p_badupdate; + char p_otherescapes[PROPS_MAXOTHERS]; + t_props *p_otherprops; /* props list's head */ + t_props *p_next; +}; + +/* 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' + 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. + Currently, p_dict is implemented as an unsorted linked list, which should + be fine in most cases (but might need revisiting LATER). */ + +static t_propelem *propelem_new(char *key, char *value) +{ + t_propelem *ep = (t_propelem *)getbytes(sizeof(*ep)); + ep->e_key = getbytes(strlen(key) + 1); + strcpy(ep->e_key, key); + ep->e_value = getbytes(strlen(value) + 1); + strcpy(ep->e_value, value); + ep->e_next = 0; + return (ep); +} + +static void propelem_free(t_propelem *ep) +{ + if (ep->e_key) freebytes(ep->e_key, strlen(ep->e_key) + 1); + if (ep->e_value) freebytes(ep->e_value, strlen(ep->e_value) + 1); + freebytes(ep, sizeof(*ep)); +} + +/* Returns zero if the key was found (and value replaced), + nonzero if a new element was added. */ +static t_propelem *propelem_add(t_propelem *ep, char *key, char *value) +{ + while (ep) + { + if (strcmp(ep->e_key, key)) + ep = ep->e_next; + else + break; + } + if (ep) + { + if (strcmp(ep->e_value, value)) + { + if (ep->e_value) + ep->e_value = resizebytes(ep->e_value, strlen(ep->e_value) + 1, + strlen(value) + 1); + else + ep->e_value = getbytes(strlen(value) + 1); + strcpy(ep->e_value, value); + } + return (0); + } + else return (propelem_new(key, value)); +} + +static void props_dictadd(t_props *pp, t_symbol *s, int ac, t_atom *av) +{ + if (s && *s->s_name && s->s_name[1] && ac) + { + t_propelem *ep; + char *value = pp->p_resolver(pp->p_owner, ac, av); + if (value && + (ep = propelem_add(pp->p_dict, s->s_name + 1, value))) + { + ep->e_next = pp->p_dict; + pp->p_dict = ep; + } + } +} + +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; + while (pp1) + { + if (pp1 != pp && pp1->p_thisescape == c) + return (pp1->p_thisinitial); + pp1 = pp1->p_next; + } + bug("props_otherinitial"); + post("(%c \"%s\")", c, pp->p_otherescapes); + return (0); +} + +static int props_atnext(t_props *pp, char *buf) +{ + char *otherinitial; + 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); + } + else if (*pp->p_otherescapes && strchr(pp->p_otherescapes, *buf)) + { + char c = buf[1]; + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') + || ((otherinitial = props_otherinitial(pp, *buf)) + && *otherinitial && strchr(otherinitial, c))) + return (PROPS_OTHER); + } + return (PROPS_NONE); +} + +/* 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) +{ + 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)) + break; + if (!nadd) + { + pp->p_badupdate = 1; + return (0); + } + pp->p_badupdate = 0; + nadd++; + for (ibeg = 0, ap = pp->p_buffer; ibeg < pp->p_natoms; ibeg++, ap++) + { + if (ap->a_type == A_SYMBOL && ap->a_w.w_symbol == s) + { + 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)) + break; + break; + } + } + ndiff = (iend > ibeg ? nadd - (iend - ibeg) : nadd); + if (doit) + { + int i, newnatoms = pp->p_natoms + ndiff; + if (newnatoms > pp->p_size) + { + bug("props_update"); + return (0); + } +#ifdef PROPS_DEBUG + post("%s %s, [%d..%d), ndiff %d", + (iend > ibeg ? "replacing" : "adding"), s->s_name, + ibeg, iend, ndiff); +#endif + if (iend > ibeg) + { + if (ndiff > 0) + { + t_atom *ap2 = pp->p_buffer + newnatoms; + t_atom *ap1 = ap2 - ndiff; + for (i = iend; i < pp->p_natoms; i++) *--ap2 = *--ap1; + } + else if (ndiff < 0) + { + t_atom *ap2 = pp->p_buffer + iend; + t_atom *ap1 = ap2 + ndiff; + for (i = iend; i < pp->p_natoms; i++) *ap1++ = *ap2++; + } + ap = pp->p_buffer + ibeg; + } + else + { + ap = pp->p_buffer + pp->p_natoms; + SETSYMBOL(ap, s); + } + ap++; + nadd--; + if (pp->p_resolver) props_dictadd(pp, s, nadd, av); + for (i = 0; i < nadd; i++) *ap++ = *av++; + pp->p_natoms = newnatoms; + } + 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) +{ + t_symbol *empty = 0; + t_atom *av1, *ap; + int ac1, i, ngrown = 0; + if (s && props_atstart(pp, s->s_name)) + ngrown += props_update(pp, 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)) + { + ngrown += props_update(pp, ap->a_w.w_symbol, ac - i - 1, ap + 1, 0); + if (pp->p_badupdate) + { + empty = ap->a_w.w_symbol; + break; + } + } + } + ngrown += pp->p_natoms; + if (ngrown > pp->p_size) + { + int nrequested = ngrown; + pp->p_buffer = grow_withdata(&nrequested, &pp->p_natoms, + &pp->p_size, pp->p_buffer, + PROPS_INISIZE, pp->p_bufini, + sizeof(*pp->p_buffer)); + 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++) + { + if (ap->a_type == A_SYMBOL + && props_atstart(pp, ap->a_w.w_symbol->s_name)) + { + props_update(pp, ap->a_w.w_symbol, ac - i - 1, ap + 1, 1); + if (pp->p_badupdate) + { + empty = ap->a_w.w_symbol; + break; + } + } + } + freebytes(av1, ac1 * sizeof(*av1)); +done: + return (empty); +} + +/* FIXME remove from p_dict */ +int props_remove(t_props *pp, t_symbol *s) +{ + int ac; + t_atom *av = props_getone(pp, s, &ac); + if (av) + { + int i; + t_atom *ap = av + ac; + t_atom *guard = pp->p_buffer + pp->p_natoms; + while (ap < guard) *av++ = *ap++; + pp->p_natoms -= ac; + return (1); + } + else return (0); +} + +/* LATER think about 'deep' cloning, i.e. propagating source atoms into + the destination buffer. Since cloning, unless requested by the user, + should never be persistent (source atoms should not stick to the + destination object in a .pd file), deep cloning requires introducing + a two-buffer scheme. There is no reason for deep cloning of arguments, + or handlers, but options could benefit. */ + +void props_clone(t_props *to, t_props *from) +{ + if (to->p_resolver) + { + /* LATER make this into a generic traversing method */ + int ibeg = 0, iend = 0; + t_atom *abeg = from->p_buffer; + t_atom *ap = abeg; + while (ibeg < from->p_natoms) + { + if (ap->a_type == A_SYMBOL && + props_atstart(from, 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)) + break; + props_dictadd(to, abeg->a_w.w_symbol, + iend - ibeg - 1, abeg + 1); + if (iend < from->p_natoms) + { + ibeg = iend; + abeg = ap; + } + else break; + } + else + { + ibeg++; + ap++; + } + } + } + else + { + /* LATER */ + } +} + +/* only dictionary-enabled properties handle props_...value() calls */ + +char *props_getvalue(t_props *pp, char *key) +{ + if (pp->p_resolver) + { + t_propelem *ep = pp->p_dict; + while (ep) + { + if (strcmp(ep->e_key, key)) + ep = ep->e_next; + else + return (ep->e_value); + } + } + return (0); +} + +char *props_nextvalue(t_props *pp, char **keyp) +{ + if (pp->p_nextelem) + { + char *value = pp->p_nextelem->e_value; + *keyp = pp->p_nextelem->e_key; + pp->p_nextelem = pp->p_nextelem->e_next; + return (value); + } + return (0); +} + +char *props_firstvalue(t_props *pp, char **keyp) +{ + if (pp->p_resolver) + pp->p_nextelem = pp->p_dict; + return (props_nextvalue(pp, keyp)); +} + +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))) + return (0); + for (ibeg = 0, ap = pp->p_buffer; ibeg < pp->p_natoms; ibeg++, ap++) + { + if (ap->a_type == A_SYMBOL && ap->a_w.w_symbol == s) + { + 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)) + break; + break; + } + } + if (iend > ibeg) + { + *npp = iend - ibeg; + return (pp->p_buffer + ibeg); + } + else return (0); +} + +t_atom *props_getall(t_props *pp, int *npp) +{ + *npp = pp->p_natoms; + return (pp->p_buffer); +} + +char *props_getname(t_props *pp) +{ + return (pp ? pp->p_name : "property"); +} + +static void props_freeone(t_props *pp) +{ + if (pp->p_buffer != pp->p_bufini) + freebytes(pp->p_buffer, pp->p_size * sizeof(*pp->p_buffer)); + while (pp->p_dict) + { + t_propelem *ep = pp->p_dict->e_next; + propelem_free(pp->p_dict); + pp->p_dict = ep; + } + freebytes(pp, sizeof(*pp)); +} + +void props_freeall(t_props *pp) +{ + if (pp && (pp = pp->p_otherprops)) + { + while (pp) + { + t_props *pp1 = pp->p_next; + props_freeone(pp); + pp = pp1; + } + } + else bug("props_freeall"); +} + +void props_setupothers(t_props *pp, t_props *otherprops) +{ + t_props *pp1; + pp->p_next = (otherprops ? otherprops->p_otherprops : 0); + for (pp1 = pp; pp1; pp1 = pp1->p_next) + { + t_props *pp2; + char *bp = pp1->p_otherescapes; + int i; + pp1->p_otherprops = pp; + for (pp2 = pp, i = 1; pp2 && i < PROPS_MAXOTHERS; + pp2 = pp2->p_next, i++) + if (pp2 != pp1) + *bp++ = pp2->p_thisescape; + *bp = 0; +#ifdef PROPS_DEBUG + startpost("%c \"%s\" ", pp1->p_thisescape, pp1->p_otherescapes); +#endif + } +#ifdef PROPS_DEBUG + endpost(); +#endif +} + +/* nonzero resolver requires the owner to be nonzero */ +t_props *props_new(t_pd *owner, char *name, char *thisdelim, + t_props *otherprops, t_propsresolver resolver) +{ + t_props *pp = getbytes(sizeof(*pp)); + if (pp) + { + pp->p_name = name; + if (thisdelim && *thisdelim) + { + pp->p_thisescape = *thisdelim++; + pp->p_thisinitial = (*thisdelim ? thisdelim : 0); + } + else + { + bug("props_new (no escape)"); + pp->p_thisescape = '-'; + pp->p_thisinitial = 0; + } + props_setupothers(pp, otherprops); + pp->p_size = PROPS_INISIZE; + pp->p_natoms = 0; + pp->p_buffer = pp->p_bufini; + if (pp->p_owner = owner) + pp->p_resolver = resolver; + else + { + if (resolver) + bug("props_new (no owner)"); + pp->p_resolver = 0; + } + pp->p_dict = 0; + pp->p_nextelem = 0; + } + return (pp); +} diff --git a/shared/common/props.h b/shared/common/props.h new file mode 100644 index 0000000..0eef345 --- /dev/null +++ b/shared/common/props.h @@ -0,0 +1,26 @@ +/* Copyright (c) 2003 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#ifndef __PROPS_H__ +#define __PROPS_H__ + +EXTERN_STRUCT _props; +#define t_props 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); +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); +char *props_firstvalue(t_props *pp, char **keyp); +char *props_nextvalue(t_props *pp, char **keyp); +t_atom *props_getone(t_props *pp, t_symbol *s, int *npp); +t_atom *props_getall(t_props *pp, int *npp); +char *props_getname(t_props *pp); +void props_freeall(t_props *pp); +t_props *props_new(t_pd *owner, char *name, char *thisdelim, + t_props *otherprops, t_propsresolver resolver); + +#endif diff --git a/shared/toxy/Makefile b/shared/toxy/Makefile new file mode 100644 index 0000000..5dcb2c8 --- /dev/null +++ b/shared/toxy/Makefile @@ -0,0 +1,4 @@ +ROOT_DIR = ../.. +include $(ROOT_DIR)/Makefile.common + +all: $(OBJECTS) diff --git a/shared/toxy/Makefile.objects b/shared/toxy/Makefile.objects new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/shared/toxy/Makefile.objects diff --git a/shared/toxy/Makefile.sources b/shared/toxy/Makefile.sources new file mode 100644 index 0000000..5f34f42 --- /dev/null +++ b/shared/toxy/Makefile.sources @@ -0,0 +1,2 @@ +OTHER_SOURCES = \ +scriptlet.c diff --git a/shared/toxy/scriptlet.c b/shared/toxy/scriptlet.c new file mode 100644 index 0000000..2592cee --- /dev/null +++ b/shared/toxy/scriptlet.c @@ -0,0 +1,666 @@ +/* Copyright (c) 2003 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#include <stdio.h> +#include <string.h> +#ifdef UNIX +#include <unistd.h> +#endif +#ifdef NT +#include <io.h> +#endif +#include "m_pd.h" +#include "g_canvas.h" +#include "common/loud.h" +#include "common/grow.h" +#include "common/props.h" +#include "scriptlet.h" + +//#define SCRIPTLET_DEBUG + +#define SCRIPTLET_INISIZE 1024 +#define SCRIPTLET_MARGIN 64 +#define SCRIPTLET_MAXARGS 9 /* do not increase (parser's constraint) */ +#define SCRIPTLET_MAXPUSH 20000 /* Tcl limit? LATER investigate */ + +enum { SCRIPTLET_CVOK, SCRIPTLET_CVUNKNOWN, SCRIPTLET_CVMISSING }; + +struct _scriptlet +{ + t_pd *s_owner; + t_glist *s_glist; /* containing glist (possibly null) */ + t_symbol *s_rptarget; /* reply target */ + t_symbol *s_cbtarget; /* callback target */ + t_symbol *s_item; + t_scriptlet_cvfn s_cvfn; + t_canvas *s_cv; + int s_cvstate; + int s_size; + char *s_buffer; + char s_bufini[SCRIPTLET_INISIZE]; + char *s_head; /* ptr to the command part of a scriptlet */ + char *s_tail; + char s_separator; /* current separator, set before a new token */ + int s_ac; /* the actual count */ + t_atom s_av[SCRIPTLET_MAXARGS]; /* always padded with zeros (if used) */ +}; + +static t_canvas *scriptlet_canvasvalidate(t_scriptlet *sp, int visedonly) +{ + t_canvas *cv; + if (sp->s_cvstate == SCRIPTLET_CVUNKNOWN) + { + if (sp->s_cvfn) + cv = sp->s_cv = sp->s_cvfn(sp->s_owner); + else + { + bug("scriptlet_canvasvalidate"); + return (0); + } + if (cv && (!visedonly || glist_isvisible(cv))) + sp->s_cvstate = SCRIPTLET_CVOK; + else + sp->s_cvstate = SCRIPTLET_CVMISSING; + } + else cv = sp->s_cv; + return (sp->s_cvstate == SCRIPTLET_CVOK ? cv : 0); +} + +static int scriptlet_ready(t_scriptlet *sp) +{ + int len = sp->s_tail - sp->s_head; + if (len > 0 && *sp->s_head && sp->s_cvstate != SCRIPTLET_CVMISSING) + { + if (len < SCRIPTLET_MAXPUSH) + return (1); + else + loud_error(sp->s_owner, + "scriptlet too long to be pushed (%d bytes)", len); + } + return (0); +} + +static int scriptlet_doappend(t_scriptlet *sp, char *buf) +{ + if (buf) + { + int nprefix = sp->s_head - sp->s_buffer; + int nused = sp->s_tail - sp->s_buffer; + int newsize = nused + strlen(buf) + SCRIPTLET_MARGIN; + if (newsize > sp->s_size) + { + int nrequested = newsize; + sp->s_buffer = grow_withdata(&nrequested, &nused, + &sp->s_size, sp->s_buffer, + SCRIPTLET_INISIZE, sp->s_bufini, + sizeof(*sp->s_buffer)); + if (nrequested != newsize) + { + scriptlet_reset(sp); + return (0); + } + sp->s_head = sp->s_buffer + nprefix; + sp->s_tail = sp->s_buffer + nused; + } + if (sp->s_separator && sp->s_tail > sp->s_head) + *sp->s_tail++ = sp->s_separator; + *sp->s_tail = 0; + strcpy(sp->s_tail, buf); + sp->s_tail += strlen(sp->s_tail); + } + sp->s_separator = 0; + return (1); +} + +static char *scriptlet_dedot(t_scriptlet *sp, char *ibuf, char *obuf, + int resolveall, int visedonly, + int ac, t_atom *av, t_props *argprops) +{ + int len = 0; + switch (*ibuf) + { + case '#': + /* ac is ignored -- assuming av is padded to SCRIPTLET_MAXARGS atoms */ + if (resolveall) + { + int which = ibuf[1] - '1'; + if (which >= 0 && which < SCRIPTLET_MAXARGS) + { + if (av) + { + if (av[which].a_type == A_FLOAT) + { + sprintf(obuf, "%g", av[which].a_w.w_float); + len = 2; + } + else if (av[which].a_type == A_SYMBOL) + { + strcpy(obuf, av[which].a_w.w_symbol->s_name); + len = 2; + } + } + } + else if (argprops) + { + char *ptr; + int cnt; + for (ptr = ibuf + 1, cnt = 1; *ptr; ptr++, cnt++) + { + char c = *ptr; + if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z')) + { + cnt = 0; + break; + } + } + if (cnt && (ptr = props_getvalue(argprops, ibuf + 1))) + { + strcpy(obuf, ptr); + len = cnt; + } + } + } + break; + case '-': + if (resolveall && sp->s_item) + { + t_canvas *cv; + if (cv = scriptlet_canvasvalidate(sp, visedonly)) + { + sprintf(obuf, ".x%x.c.%s%x", (int)cv, sp->s_item->s_name, + (int)sp->s_owner); + len = 1; + } + } + break; + case '^': + if (resolveall) + { + t_canvas *cv; + if (cv = scriptlet_canvasvalidate(sp, visedonly)) + { + sprintf(obuf, ".x%x", (int)cv); + len = 1; + } + } + break; + case '|': + if (resolveall) + { + strcpy(obuf, sp->s_cbtarget->s_name); + len = 1; + } + break; + case '~': + if (resolveall) + { + t_canvas *cv; + if (cv = scriptlet_canvasvalidate(sp, visedonly)) + { + /* FIXME */ + if (!strcmp(&ibuf[1], "x1")) + { + sprintf(obuf, "%d", cv->gl_screenx1); + len = 3; + } + else if (!strcmp(&ibuf[1], "x2")) + { + sprintf(obuf, "%d", cv->gl_screenx2); + len = 3; + } + else if (!strcmp(&ibuf[1], "y1")) + { + sprintf(obuf, "%d", cv->gl_screeny1); + len = 3; + } + else if (!strcmp(&ibuf[1], "y2")) + { + sprintf(obuf, "%d", cv->gl_screeny2); + len = 3; + } + else if (!strcmp(&ibuf[1], "edit")) + { + sprintf(obuf, "%d", cv->gl_edit); + len = 5; + } + else loud_error(sp->s_owner, "bad field '%s'", &ibuf[1]); + } + } + break; + case '`': + sprintf(obuf, "\\"); + len = 1; + break; + case ':': + sprintf(obuf, ";"); + len = 1; + break; + case '(': + sprintf(obuf, "{"); + len = 1; + break; + case ')': + sprintf(obuf, "}"); + len = 1; + break; + case '<': + if (resolveall) + { + if (ibuf[1] == ':') + { + sprintf(obuf, "{::toxy::callback "); + len = 2; + } + else if (ibuf[1] == '|') + { + sprintf(obuf, "{::toxy::callback %s ", + sp->s_rptarget->s_name); + len = 2; + } + else + { + sprintf(obuf, "{::toxy::callback %s _cb ", + sp->s_cbtarget->s_name); + len = 1; + } + } + break; + case '>': + if (resolveall) + { + sprintf(obuf, "}"); + len = 1; + } + break; + } + return (len ? ibuf + len : 0); +} + +void scriptlet_reset(t_scriptlet *sp) +{ + sp->s_cvstate = SCRIPTLET_CVUNKNOWN; + sp->s_separator = 0; + strcpy(sp->s_buffer, "namespace eval ::toxy {\ + proc query {} {set ::toxy::reply [\n"); + sp->s_head = sp->s_tail = sp->s_buffer + strlen(sp->s_buffer); +} + +void scriptlet_prealloc(t_scriptlet *sp, int sz, int mayshrink) +{ + if (sz < SCRIPTLET_INISIZE) + sz = SCRIPTLET_INISIZE; + if (sz < sp->s_size && mayshrink) + { + if (sp->s_buffer != sp->s_bufini) + freebytes(sp->s_buffer, sp->s_size * sizeof(*sp->s_buffer)); + else + bug("scriptlet_prealloc"); + sp->s_size = SCRIPTLET_INISIZE; + sp->s_buffer = sp->s_bufini; + } + if (sz > sp->s_size) + sp->s_buffer = grow_nodata(&sz, &sp->s_size, sp->s_buffer, + SCRIPTLET_INISIZE, sp->s_bufini, + sizeof(*sp->s_buffer)); + scriptlet_reset(sp); +} + +int scriptlet_addstring(t_scriptlet *sp, char *ibuf, + int resolveall, int visedonly, + int ac, t_atom *av, t_props *argprops) +{ + int result = 1; + char *bp = ibuf, *ep = ibuf, *ep1; + char dotbuf[64]; /* LATER reestimation */ + if (!sp->s_separator) + sp->s_separator = ' '; + while (*ep) + { + if (*ep == '.' + && (ep1 = scriptlet_dedot(sp, ep + 1, dotbuf, + resolveall, visedonly, ac, av, argprops))) + { + *ep = 0; + if (!(result = scriptlet_doappend(sp, bp))) + break; + *ep = '.'; + if (!(result = scriptlet_doappend(sp, dotbuf))) + break; + bp = ep = ep1; + } + else ep++; + } + if (result) + result = scriptlet_doappend(sp, bp); + sp->s_separator = 0; + return (result); +} + +int scriptlet_addfloat(t_scriptlet *sp, t_float f) +{ + char buf[64]; + if (!sp->s_separator) + sp->s_separator = ' '; + sprintf(buf, "%g ", f); + return (scriptlet_doappend(sp, buf)); +} + +int scriptlet_add(t_scriptlet *sp, + int resolveall, int visedonly, int ac, t_atom *av) +{ + while (ac--) + { + int result = 1; + if (av->a_type == A_SYMBOL) + result = scriptlet_addstring(sp, av->a_w.w_symbol->s_name, + resolveall, visedonly, 0, 0, 0); + else if (av->a_type == A_FLOAT) + result = scriptlet_addfloat(sp, av->a_w.w_float); + if (!result) + return (0); + av++; + } + return (1); +} + +void scriptlet_setseparator(t_scriptlet *sp, char c) +{ + sp->s_separator = c; +} + +void scriptlet_push(t_scriptlet *sp) +{ + if (scriptlet_ready(sp)) + { + char *tail = sp->s_tail; + strcpy(tail, "\n"); + sys_gui(sp->s_head); + *tail = 0; + } +} + +void scriptlet_qpush(t_scriptlet *sp) +{ + if (scriptlet_ready(sp)) + { + char buf[MAXPDSTRING]; + char *tail = sp->s_tail; + strcpy(tail, "]}}\n"); + sys_gui(sp->s_buffer); + *tail = 0; + sprintf(buf, "after 0 {::toxy::query}\nvwait ::toxy::reply\n\ + pd [concat %s _rp $::toxy::reply \\;]\n", sp->s_rptarget->s_name); + sys_gui(buf); + } +} + +int scriptlet_evaluate(t_scriptlet *insp, t_scriptlet *outsp, + int visedonly, int ac, t_atom *av, t_props *argprops) +{ + if (scriptlet_ready(insp)) + { + t_atom *ap; + int i; + char *bp; + char separator = 0; + insp->s_ac = ac; + for (i = 0, ap = insp->s_av; i < SCRIPTLET_MAXARGS; i++, ap++) + { + if (ac) + { + if (av->a_type == A_FLOAT || + (av->a_type == A_SYMBOL && av->a_w.w_symbol)) + *ap = *av; + else + SETFLOAT(ap, 0); + ac--; av++; + } + else SETFLOAT(ap, 0); + } + /* FIXME pregrowing of the transient scriptlet */ + scriptlet_reset(outsp); + /* LATER abstract this into scriptlet_parse() */ + bp = insp->s_head; + while (*bp) + { + if (*bp == '\n') + separator = '\n'; + else if (*bp == ' ' || *bp == '\t') + { + if (!separator) separator = ' '; + } + else + { + int done = 1; + char *ep = bp; + char c = ' '; + while (*++ep) + { + if (*ep == ' ' || *bp == '\t' || *ep == '\n') + { + done = 0; + c = *ep; + *ep = 0; + break; + } + } + outsp->s_separator = separator; + scriptlet_addstring(outsp, bp, 1, visedonly, + ac, insp->s_av, argprops); + if (done) + break; + *ep = c; + bp = ep; + separator = (c == '\t' ? ' ' : c); + } + bp++; + } + return (outsp->s_cvstate != SCRIPTLET_CVMISSING); + } + else return (0); +} + +/* utility function to be used in a comment-parsing callback */ +char *scriptlet_nextword(char *buf) +{ + while (*++buf) + { + if (*buf == ' ' || *buf == '\t') + { + char *ptr = buf + 1; + while (*ptr == ' ' || *ptr == '\t') ptr++; + *buf = 0; + return (*ptr ? ptr : 0); + } + } + return (0); +} + +static int scriptlet_doread(t_scriptlet *sp, FILE *fp, char *rc, + t_scriptlet_cmntfn cmntfn) +{ + t_scriptlet *outsp = sp, *newsp; + char buf[MAXPDSTRING]; + scriptlet_reset(outsp); + while (!feof(fp)) + { + if (fgets(buf, MAXPDSTRING - 1, fp)) + { + char *ptr = buf; + while (*ptr == ' ' || *ptr == '\t') ptr++; + if (*ptr == '#') + { + if (cmntfn) + { + char sel = *++ptr; + if (sel && sel != '\n') + { + ptr++; + while (*ptr == ' ' || *ptr == '\t') ptr++; + if (*ptr == '\n') + *ptr = 0; + if (*ptr) + { + char *ep = ptr + strlen(ptr) - 1; + while (*ep == ' ' || *ep == '\t' || *ep == '\n') + ep--; + ep[1] = 0; + } + newsp = cmntfn(sp->s_owner, rc, sel, ptr); + if (newsp && newsp != outsp) + scriptlet_reset(outsp = newsp); + } + } + } + else if (*ptr && *ptr != '\n') + scriptlet_doappend(outsp, buf); + } + else break; + } + return (SCRIPTLET_OK); +} + +int scriptlet_rcload(t_scriptlet *sp, char *rc, char *ext, + t_scriptlet_cmntfn cmntfn) +{ + char filename[MAXPDSTRING], buf[MAXPDSTRING], *nameptr, *dir; + int fd; + if (sp->s_glist) + dir = canvas_getdir(sp->s_glist)->s_name; + else + dir = ""; + if ((fd = open_via_path(dir, rc, ext, buf, &nameptr, MAXPDSTRING, 0)) < 0) + { + return (SCRIPTLET_NOFILE); + } + else + { + FILE *fp; + close(fd); + strcpy(filename, buf); + strcat(filename, "/"); + strcat(filename, nameptr); + sys_bashfilename(filename, filename); + if (fp = fopen(filename, "r")) + { + int result = scriptlet_doread(sp, fp, rc, cmntfn); + fclose(fp); + return (result); + } + else + { + bug("scriptlet_rcload"); + return (SCRIPTLET_NOFILE); + } + } +} + +int scriptlet_read(t_scriptlet *sp, t_symbol *fn) +{ + FILE *fp; + char buf[MAXPDSTRING]; + post("loading scriptlet file \"%s\"", fn->s_name); + if (sp->s_glist) + canvas_makefilename(sp->s_glist, fn->s_name, buf, MAXPDSTRING); + else + strncpy(buf, fn->s_name, MAXPDSTRING); + sys_bashfilename(buf, buf); + if (fp = fopen(buf, "r")) + { + int result = scriptlet_doread(sp, fp, 0, 0); + fclose(fp); + return (result); + } + else + { + loud_error(sp->s_owner, "error while loading file \"%s\"", fn->s_name); + return (SCRIPTLET_NOFILE); + } +} + +int scriptlet_write(t_scriptlet *sp, t_symbol *fn) +{ + int size = sp->s_tail - sp->s_head; + if (size > 0 && *sp->s_head) + { + FILE *fp; + char buf[MAXPDSTRING]; + post("saving scriptlet file \"%s\"", fn->s_name); + if (sp->s_glist) + canvas_makefilename(sp->s_glist, fn->s_name, buf, MAXPDSTRING); + else + strncpy(buf, fn->s_name, MAXPDSTRING); + sys_bashfilename(buf, buf); + if (fp = fopen(buf, "w")) + { + int result = fwrite(sp->s_head, 1, size, fp); + fclose(fp); + if (result == size) + return (SCRIPTLET_OK); + } + loud_error(sp->s_owner, "error while saving file \"%s\"", fn->s_name); + return (fp ? SCRIPTLET_BADFILE : SCRIPTLET_NOFILE); + } + else + { + loud_warning(sp->s_owner, "empty scriptlet not written"); + return (SCRIPTLET_IGNORED); + } +} + +char *scriptlet_getcontents(t_scriptlet *sp, int *lenp) +{ + *lenp = sp->s_tail - sp->s_head; + return (sp->s_head); +} + +char *scriptlet_getbuffer(t_scriptlet *sp, int *sizep) +{ + *sizep = sp->s_size; + return (sp->s_buffer); +} + +void scriptlet_clone(t_scriptlet *to, t_scriptlet *from) +{ + scriptlet_reset(to); + to->s_separator = ' '; + /* LATER use from's buffer with refcount */ + scriptlet_doappend(to, from->s_head); +} + +void scriptlet_free(t_scriptlet *sp) +{ + if (sp) + { + if (sp->s_buffer != sp->s_bufini) + freebytes(sp->s_buffer, sp->s_size * sizeof(*sp->s_buffer)); + freebytes(sp, sizeof(*sp)); + } +} + +t_scriptlet *scriptlet_new(t_pd *owner, t_symbol *rptarget, t_symbol *cbtarget, + t_symbol *item, t_scriptlet_cvfn cvfn) +{ + t_scriptlet *sp = getbytes(sizeof(*sp)); + if (sp) + { + static int configured = 0; + if (!configured) + { + sys_gui("namespace eval ::toxy {\ + proc callback {args} {pd $args \\;}}\n"); + sys_gui("image create bitmap ::toxy::img::empty -data {}\n"); + } + sp->s_owner = owner; + sp->s_glist = canvas_getcurrent(); + sp->s_rptarget = rptarget; + sp->s_cbtarget = cbtarget; + sp->s_item = item; + sp->s_cvfn = cvfn; + sp->s_size = SCRIPTLET_INISIZE; + sp->s_buffer = sp->s_bufini; + scriptlet_reset(sp); + } + return (sp); +} diff --git a/shared/toxy/scriptlet.h b/shared/toxy/scriptlet.h new file mode 100644 index 0000000..4b057b9 --- /dev/null +++ b/shared/toxy/scriptlet.h @@ -0,0 +1,42 @@ +/* Copyright (c) 2003 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#ifndef __SCRIPTLET_H__ +#define __SCRIPTLET_H__ + +enum { SCRIPTLET_OK = 0, SCRIPTLET_NOFILE, SCRIPTLET_BADFILE, + SCRIPTLET_IGNORED }; + +EXTERN_STRUCT _scriptlet; +#define t_scriptlet struct _scriptlet + +typedef t_canvas *(*t_scriptlet_cvfn)(t_pd *); +typedef t_scriptlet *(*t_scriptlet_cmntfn)(t_pd *, char *, char, char *); + +void scriptlet_reset(t_scriptlet *sp); +void scriptlet_prealloc(t_scriptlet *sp, int sz, int mayshrink); +int scriptlet_add(t_scriptlet *sp, + int resolveall, int visedonly, int ac, t_atom *av); +int scriptlet_addstring(t_scriptlet *sp, char *ibuf, + int resolveall, int visedonly, + int ac, t_atom *av, t_props *argprops); +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); +int scriptlet_evaluate(t_scriptlet *insp, t_scriptlet *outsp, + int visedonly, int ac, t_atom *av, t_props *argprops); +char *scriptlet_nextword(char *buf); +int scriptlet_rcload(t_scriptlet *sp, char *rc, char *ext, + t_scriptlet_cmntfn cmntfn); +int scriptlet_read(t_scriptlet *sp, t_symbol *fn); +int scriptlet_write(t_scriptlet *sp, t_symbol *fn); +char *scriptlet_getcontents(t_scriptlet *sp, int *lenp); +char *scriptlet_getbuffer(t_scriptlet *sp, int *sizep); +void scriptlet_clone(t_scriptlet *to, t_scriptlet *from); +void scriptlet_free(t_scriptlet *sp); +t_scriptlet *scriptlet_new(t_pd *owner, t_symbol *rptarget, t_symbol *cbtarget, + t_symbol *item, t_scriptlet_cvfn cvfn); + +#endif diff --git a/test/toxy/button-test.pd b/test/toxy/button-test.pd new file mode 100644 index 0000000..1f553dd --- /dev/null +++ b/test/toxy/button-test.pd @@ -0,0 +1,37 @@ +#N canvas 106 44 636 366 12; +#X obj 21 259 widget button b -bg red -activebackground yellow -text +red -command .<.>; +#X msg 130 162 -command .<.>; +#X msg 48 295 debug; +#X obj 21 324 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X obj 193 268 r t1; +#X obj 193 324 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X msg 45 74 -bg pink -text pink; +#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 connect 0 0 3 0; +#X connect 1 0 0 0; +#X connect 2 0 0 0; +#X connect 4 0 5 0; +#X connect 6 0 0 0; +#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 13 0 0 0; +#X connect 14 0 0 0; +#X connect 15 0 0 0; +#X connect 16 0 15 0; diff --git a/test/toxy/default.wid b/test/toxy/default.wid new file mode 100644 index 0000000..e9a20a1 --- /dev/null +++ b/test/toxy/default.wid @@ -0,0 +1,108 @@ +# first the setup stuff (is this the right place for it?) + +# LATER ask for adding something of the sort to pd.tk: +bind Canvas <1> {+focus %W} + +proc ::toxy::popup {path target remote entries args} { + eval {menu $path.pop} $args + set i 1 + foreach e $entries { + $path.pop add command -label [lindex $e 0] \ + -command [concat ::toxy::callback $target \ + -text [lindex $e [expr {[llength $e] > 1}]] \; \ + ::toxy::callback $remote $i] + incr i + } +} + +proc ::toxy::kb {path target remote noctaves size} { + set lft [expr {round(5 * $size)}] + set top [expr {5 * $size}] + set bot [expr {100 * $size}] + set dx [expr {round(17 * $size)}] + set wid [expr {$dx - $size * .5}] + set blbot [expr {$bot * .65}] + + $path config -height [expr {$bot + $top}] \ + -width [expr {$dx * ($noctaves * 7 + 1) + $lft * 2 - 1}] + + for {set octave 0} {$octave <= $noctaves} {incr octave} { + set prevkey 0 + foreach key {0 2 4 5 7 9 11} { + set ndx [expr $octave * 12 + $key] + set id [$path create rect $lft $top \ + [expr {$lft + $wid}] $bot -fill white -tags $path.$ndx] + $path bind $id <1> [concat ::toxy::kbset \ + $path $target $remote $ndx] + if {$key - $prevkey > 1} { + incr ndx -1 + set x [expr {$lft - $wid * .22}] + set id [$path create rect $x $top [expr {$x + $wid * .44}] \ + $blbot -fill black -tags $path.$ndx] + $path bind $id <1> [concat ::toxy::kbset \ + $path $target $remote $ndx] + } + set prevkey $key + incr lft $dx + if {$octave == $noctaves && $key == 0} break + } + } + set ::toxy::kbval($target) 0 + set ::toxy::kbcol($target) white + $path itemconfig $path.0 -fill grey +} + +proc ::toxy::kbout {path target remote} { + ::toxy::callback $target _cb $::toxy::kbval($target) + if {$remote != "."} {::toxy::callback $remote $::toxy::kbval($target)} +} + +proc ::toxy::kbset {path target remote value} { + $path itemconfig $path.$::toxy::kbval($target) \ + -fill $::toxy::kbcol($target) + set ::toxy::kbval($target) $value + set ::toxy::kbcol($target) [lindex [$path itemconfig $path.$value -fill] 4] + $path itemconfig $path.$value -fill grey + ::toxy::kbout $path $target $remote +} + +# the default initializer +#> default + +# pdtk_canvas_mouseup is a hack, which we must call anyway +bind .- <ButtonRelease> { + eval .<|_inout 1.> + pdtk_canvas_mouseup .^.c [expr %x + [winfo x %W]] [expr %y + [winfo y %W]] %b +} + +bind .- <1> .<|_click %x %y %b 0.> +bind .- <3> .<|_click %x %y %b 8.> +bind .- <Motion> .<|_motion %x %y.> +bind .- <Enter> .<|_inout 1.> +bind .- <Leave> .<|_inout 0.> + +#> bang button +#. -image ::toxy::img::empty -command .<.> +#. -bg pink -activebackground red -width 50 -height 50 +#. @bang .- flash .: .- invoke + +#> float scale +#. -command .<.> -bg pink -activebackground red -length 200 +#. @float .- set .#1 + +#> symbol entry +#. -bg pink -font .(helvetica 24.) -width 16 +#. @symbol .- delete 0 end .: .- insert 0 .#1 + +bind .- <Return> {eval .<[.- get].>; focus .^.c} + +#> kb canvas +#. -bg yellow -cursor hand1 +#. #oct 4 #size .75 +#. @bang ::toxy::kbout .- .| . +#. @float ::toxy::kbset .- .| . .#1 + +::toxy::kb .- .| . .#oct .#size + +# undo the "bind Canvas <1> {+focus %W}" in the setup part above +bind .- <FocusIn> {focus .^.c} diff --git a/test/toxy/defaults-test.pd b/test/toxy/defaults-test.pd new file mode 100644 index 0000000..c0c5aaf --- /dev/null +++ b/test/toxy/defaults-test.pd @@ -0,0 +1,25 @@ +#N canvas 281 172 504 371 12; +#X obj 247 89 widget bang b; +#X obj 33 89 widget float f; +#X obj 124 247 widget symbol s; +#X floatatom 33 325 5 0 0 0 - - -; +#X obj 247 175 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 124 325 print; +#X msg 33 20 debug; +#X msg 247 20 bang; +#X msg 307 55 remove @bang; +#X msg 307 20 @bang .- invoke; +#X floatatom 121 20 5 0 0 0 - - -; +#X msg 124 206 symbol test; +#X connect 0 0 4 0; +#X connect 1 0 3 0; +#X connect 2 0 5 0; +#X connect 6 0 0 0; +#X connect 6 0 1 0; +#X connect 6 0 2 0; +#X connect 7 0 0 0; +#X connect 8 0 0 0; +#X connect 9 0 0 0; +#X connect 10 0 1 0; +#X connect 11 0 2 0; diff --git a/test/toxy/kb-test.pd b/test/toxy/kb-test.pd new file mode 100644 index 0000000..2978dce --- /dev/null +++ b/test/toxy/kb-test.pd @@ -0,0 +1,17 @@ +#N canvas 354 116 645 486 12; +#X obj 37 61 widget kb k1; +#X floatatom 37 160 5 0 0 0 - - -; +#X obj 37 310 widget kb k2 #oct 8 #size 0.35 -bg red; +#X floatatom 37 369 5 0 0 0 - - -; +#X msg 120 271 #oct \$1 \, refresh; +#X floatatom 120 237 5 0 0 0 - - -; +#X floatatom 37 24 5 0 0 0 - - -; +#X msg 114 24 bang; +#X floatatom 37 237 5 0 0 0 - - -; +#X connect 0 0 1 0; +#X connect 2 0 3 0; +#X connect 4 0 2 0; +#X connect 5 0 4 0; +#X connect 6 0 0 0; +#X connect 7 0 0 0; +#X connect 8 0 2 0; diff --git a/test/toxy/listbox-test.pd b/test/toxy/listbox-test.pd new file mode 100644 index 0000000..cd1fa46 --- /dev/null +++ b/test/toxy/listbox-test.pd @@ -0,0 +1,18 @@ +#N canvas 154 52 626 383 12; +#X obj 281 144 widget listbox lb -width 32 -height 12 -bg black -fg +white; +#X obj 20 282 tow . listbox lb; +#X obj 20 21 loadbang; +#X msg 20 52 ini foreach fn [lsort [glob *]] .(.- insert end $fn.) +; +#X obj 236 143 widget button b -text ok -height 14 -bg black -fg white +-command .<.>; +#X obj 112 21 tow . button b; +#X msg 36 83 tot if .([.- curselection] != "".) .(eval .<set [.- get +[.- curselection]].>.); +#X msg 20 324; +#X connect 1 0 7 0; +#X connect 2 0 3 0; +#X connect 3 0 1 0; +#X connect 5 0 6 0; +#X connect 6 0 1 0; diff --git a/test/toxy/pop1.wid b/test/toxy/pop1.wid new file mode 100644 index 0000000..88b6595 --- /dev/null +++ b/test/toxy/pop1.wid @@ -0,0 +1,10 @@ +#> pop1 menubutton +#. -menu .-.pop +#. -bg purple -fg white -activebackground magenta -width 8 -text jeden +#. @float if .(.#1 >= 1.) .(.-.pop invoke .#1.) + +::toxy::popup .- .| rpop1 \ + [list {one jeden} {two dwa} {three trzy} \ + {four cztery} {five piêæ} {six sze¶æ} {seven siedem} \ + {eight osiem} {nine dziewiêæ} {ten dziesiêæ}] \ + -bg purple -fg white -activebackground magenta diff --git a/test/toxy/pop2.wid b/test/toxy/pop2.wid new file mode 100644 index 0000000..8f7ccf5 --- /dev/null +++ b/test/toxy/pop2.wid @@ -0,0 +1,8 @@ +#> pop2 menubutton +#. -menu .-.pop +#. -bg purple -fg white -activebackground magenta -width 6 -text kura +#. @float if .(.#1 >= 1.) .(.-.pop invoke .#1.) + +::toxy::popup .- .| rpop2 \ + [list {hen kura} {duck kaczka} {cat kot} {cow krowa} {horse koñ}] \ + -bg purple -fg white -activebackground magenta diff --git a/test/toxy/popup-test.pd b/test/toxy/popup-test.pd new file mode 100644 index 0000000..7f49162 --- /dev/null +++ b/test/toxy/popup-test.pd @@ -0,0 +1,39 @@ +#N canvas 356 9 338 241 12; +#X obj 38 104 r rpop; +#X floatatom 38 142 5 0 0 0 - - -; +#X floatatom 120 142 5 0 0 0 - - -; +#X obj 120 104 r rpop1; +#X floatatom 210 142 5 0 0 0 - - -; +#X obj 210 104 r rpop2; +#N canvas 12 11 293 279 blackpanel 1; +#X obj 23 111 widget menubutton mb -menu .-.pop -bg green -activebackground +yellow -width 5 -text one @float if .(.#1 >= 1.) .(.-.pop invoke .#1.) +; +#X obj 23 12 loadbang; +#X obj 96 110 widget pop1 p1; +#X obj 188 110 widget pop2 p2; +#X msg 23 41 ini ::toxy::popup .- .| rpop [list one two three four five] +-bg green -activebackground yellow .: destroy .^.m .: .^.scrollvert +configure -width 0 .: .^.scrollhort configure -width 0 .: .^.c configure +-bg black; +#X obj 23 150 r topop; +#X obj 96 150 r topop1; +#X obj 188 150 r topop2; +#X connect 1 0 4 0; +#X connect 4 0 0 0; +#X connect 5 0 0 0; +#X connect 6 0 2 0; +#X connect 7 0 3 0; +#X restore 95 198 pd blackpanel; +#X floatatom 38 24 5 0 0 0 - - -; +#X floatatom 120 24 5 0 0 0 - - -; +#X floatatom 210 24 5 0 0 0 - - -; +#X obj 38 58 s topop; +#X obj 120 58 s topop1; +#X obj 210 58 s topop2; +#X connect 0 0 1 0; +#X connect 3 0 2 0; +#X connect 5 0 4 0; +#X connect 7 0 10 0; +#X connect 8 0 11 0; +#X connect 9 0 12 0; diff --git a/test/toxy/radio-test.pd b/test/toxy/radio-test.pd new file mode 100644 index 0000000..24e1a3b --- /dev/null +++ b/test/toxy/radio-test.pd @@ -0,0 +1,50 @@ +#N canvas 179 90 559 300 12; +#X obj 20 158 widget radiobutton r -variable ::toxy::r -value 0 -command +.<:common $::toxy::r.> -bg orange -activebackground magenta -width +44 -height 44 -indicatoron off -image ::toxy::img::empty; +#X obj 70 158 widget radiobutton r -variable ::toxy::r -value 1 -command +.<:common $::toxy::r.> -bg orange -activebackground magenta -width +44 -height 44 -indicatoron off -image ::toxy::img::empty; +#X obj 120 158 widget radiobutton r -variable ::toxy::r -value 2 -command +.<:common $::toxy::r.> -bg orange -activebackground magenta -width +44 -height 44 -indicatoron off -image ::toxy::img::empty; +#X obj 170 158 widget radiobutton r -variable ::toxy::r -value 3 -command +.<:common $::toxy::r.> -bg orange -activebackground magenta -width +44 -height 44 -indicatoron off -image ::toxy::img::empty; +#X obj 20 221 r t0; +#X obj 70 221 r t1; +#X obj 120 221 r t2; +#X obj 170 221 r t3; +#X obj 261 260 hradio 15 1 0 4 empty empty empty 0 -6 0 8 -262144 -1 +-1 0; +#X obj 20 127 t a; +#X obj 20 260 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 70 260 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 120 260 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 170 260 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 261 222 r common; +#X msg 20 15 -command .<:common $::toxy::r.>; +#X msg 31 46 -command .<:[join [list t $::toxy::r] ""] $::toxy::r.> +; +#X obj 366 260 hradio 15 1 0 4 empty empty empty 0 -6 0 8 -262144 -1 +-1 0; +#X connect 4 0 10 0; +#X connect 4 0 8 0; +#X connect 5 0 11 0; +#X connect 5 0 8 0; +#X connect 6 0 12 0; +#X connect 6 0 8 0; +#X connect 7 0 13 0; +#X connect 7 0 8 0; +#X connect 9 0 0 0; +#X connect 9 0 1 0; +#X connect 9 0 2 0; +#X connect 9 0 3 0; +#X connect 14 0 8 0; +#X connect 14 0 17 0; +#X connect 15 0 9 0; +#X connect 16 0 9 0; diff --git a/test/toxy/scale-test.pd b/test/toxy/scale-test.pd new file mode 100644 index 0000000..e35a4a2 --- /dev/null +++ b/test/toxy/scale-test.pd @@ -0,0 +1,44 @@ +#N canvas 79 51 599 397 12; +#X obj 22 197 widget scale s -command .<.> -variable ::toxy::simplescale +-label "Simple Scale" -orient h -length 300 -width 50 -font "Helvetica +12" -from -16 -to 16 -showvalue 0 @float .- set .#1; +#X floatatom 22 336 5 0 0 0 - - -; +#X floatatom 191 128 5 0 0 0 - - -; +#X msg 191 159 -from \$1; +#X floatatom 287 128 5 0 0 0 - - -; +#X msg 287 159 -to \$1; +#X msg 44 159 -showvalue \$1; +#X obj 44 133 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X floatatom 214 336 5 0 0 0 - - -; +#X msg 36 102 -command .<.>; +#X obj 214 306 r \$0-scale; +#X msg 22 70 -command .<: \$1-scale .>; +#X obj 22 10 loadbang; +#X obj 22 40 int \$0; +#X msg 113 10 bang; +#X msg 269 67 @float .- set .#1; +#X msg 269 102 remove @float; +#X floatatom 269 40 5 0 0 0 - - -; +#N canvas 0 0 450 420 linked 0; +#X obj 54 49 widget scale s -command .<.> -variable ::toxy::simplescale +-orient v -length 300 -width 50 -font "Helvetica 12" -from -16 -to +16 -showvalue 0 @float .- set .#1; +#X coords 0 0 1 1 80 360 1; +#X restore 472 20 pd linked; +#X connect 0 0 1 0; +#X connect 2 0 3 0; +#X connect 3 0 0 0; +#X connect 4 0 5 0; +#X connect 5 0 0 0; +#X connect 6 0 0 0; +#X connect 7 0 6 0; +#X connect 9 0 0 0; +#X connect 10 0 8 0; +#X connect 11 0 0 0; +#X connect 12 0 13 0; +#X connect 13 0 11 0; +#X connect 14 0 13 0; +#X connect 15 0 0 0; +#X connect 16 0 0 0; +#X connect 17 0 0 0; diff --git a/test/toxy/test1.tot b/test/toxy/test1.tot new file mode 100644 index 0000000..3faf74e --- /dev/null +++ b/test/toxy/test1.tot @@ -0,0 +1,301 @@ +puts [concat .#0 .#1 .#9 .#: .^.c] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9] +puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 .#9]
\ No newline at end of file diff --git a/test/toxy/tot-bulk.pd b/test/toxy/tot-bulk.pd new file mode 100644 index 0000000..cefb622 --- /dev/null +++ b/test/toxy/tot-bulk.pd @@ -0,0 +1,67 @@ +#N canvas 309 244 595 546 12; +#X obj 62 449 pack; +#X obj 62 387 t b b; +#X obj 62 356 until; +#X obj 33 250 makefilename #%x; +#X obj 33 219 + 256; +#X obj 33 188 random 3840; +#X obj 62 418 random 500; +#X obj 175 418 random 500; +#X obj 33 126 + 3; +#X obj 83 6 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; +#X obj 33 33 metro 500; +#X obj 157 95 random 10; +#X obj 157 126 sel 7; +#X obj 33 64 t b b; +#X obj 175 449 + 20; +#X obj 33 6 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1 +; +#X msg 130 33 tot .^.c delete bulk; +#X msg 98 544 tot .^.c configure -bg pink; +#X msg 62 480 add [expr \$1 + .#1] [expr \$2 + .#2]; +#X msg 62 511 debug; +#X obj 33 285 pack s 0 0; +#X obj 33 157 t b b b 0 b; +#X msg 33 320 add -tags bulk -fill \$1 -smooth true \, push \$2 \$3 +; +#X msg 157 188 reset \, add .^.c create polygon; +#X obj 261 250 random 150; +#X obj 201 219 random 100; +#X obj 201 250 + 10; +#X obj 33 95 random 700; +#X obj 33 544 tot .; +#X connect 0 0 18 0; +#X connect 1 0 6 0; +#X connect 1 1 7 0; +#X connect 2 0 1 0; +#X connect 3 0 20 0; +#X connect 4 0 3 0; +#X connect 5 0 4 0; +#X connect 6 0 0 0; +#X connect 7 0 14 0; +#X connect 8 0 21 0; +#X connect 9 0 10 0; +#X connect 10 0 13 0; +#X connect 11 0 12 0; +#X connect 12 0 16 0; +#X connect 13 0 27 0; +#X connect 13 1 11 0; +#X connect 14 0 0 1; +#X connect 15 0 13 0; +#X connect 16 0 28 0; +#X connect 17 0 28 0; +#X connect 18 0 28 0; +#X connect 19 0 28 0; +#X connect 20 0 22 0; +#X connect 21 0 5 0; +#X connect 21 1 25 0; +#X connect 21 2 24 0; +#X connect 21 3 2 0; +#X connect 21 4 23 0; +#X connect 22 0 28 0; +#X connect 23 0 28 0; +#X connect 24 0 20 2; +#X connect 25 0 26 0; +#X connect 26 0 20 1; +#X connect 27 0 8 0; +#X connect 28 3 17 0; diff --git a/test/toxy/tot-cover.pd b/test/toxy/tot-cover.pd new file mode 100644 index 0000000..267c22d --- /dev/null +++ b/test/toxy/tot-cover.pd @@ -0,0 +1,87 @@ +#N canvas 392 177 590 367 12; +#X msg 58 239 cover; +#X msg 125 239 uncover; +#N canvas 354 120 500 400 cv 1; +#X restore 16 12 pd cv; +#X obj 16 305 tot cv; +#X obj 258 225 snapshot~; +#X obj 481 225 snapshot~; +#X obj 258 283 pack; +#X obj 393 195 metro 50; +#X obj 393 170 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 481 254 * 5; +#X obj 258 254 * 5; +#X msg 308 12 0 \; pd dsp 0; +#X msg 199 12 1 \; pd dsp 1; +#X obj 363 193 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 363 225 metro 500; +#X obj 363 254 random 20; +#X obj 258 170 osc~ 3; +#X obj 481 170 osc~ 7; +#X obj 199 62 pipe 3000; +#X msg 122 58 stop; +#X msg 122 29 bang; +#X obj 16 62 delay 5000; +#N canvas 80 35 613 356 commands 0; +#X obj 25 13 inlet; +#X obj 25 198 route cover uncover; +#X obj 25 306 outlet; +#X obj 48 46 loadbang; +#X msg 25 226 tot tot_cover .^.c [ expr .~x2 - .~x1 ] [ expr .~y2 - +.~y1 ]; +#X msg 42 259 tot if .( [winfo exists .^.c.cover] .) .( destroy .^.c.cover +.); +#X obj 48 145 tot .; +#X msg 48 78 tot proc tot_cover .( cv wd ht .) .( if .( [expr ![winfo +exists $cv.cover]] .) .( canvas $cv.cover -width $wd -height $ht -bg +red -bd 0 .: pack $cv.cover .) .); +#X connect 0 0 1 0; +#X connect 1 0 4 0; +#X connect 1 1 5 0; +#X connect 3 0 7 0; +#X connect 4 0 2 0; +#X connect 5 0 2 0; +#X connect 7 0 6 0; +#X restore 58 268 pd commands; +#X msg 16 91 tot .^.c create polygon 50 50 170 130 400 70 50 50 -fill +#abcdef -tags t1 \, tot .^.c create text 200 90 -text "hide me" -font +"times 24" -fill #fedcba -tags t1; +#X msg 34 170 tot .^.c delete t1; +#X msg 43 202 tot .^.c move t1 \$1 \$2; +#X msg 65 336 tot .^.c configure -bg red; +#X connect 0 0 22 0; +#X connect 1 0 22 0; +#X connect 3 3 26 0; +#X connect 4 0 10 0; +#X connect 5 0 9 0; +#X connect 6 0 25 0; +#X connect 7 0 4 0; +#X connect 7 0 5 0; +#X connect 8 0 7 0; +#X connect 9 0 6 1; +#X connect 10 0 6 0; +#X connect 11 0 8 0; +#X connect 11 0 24 0; +#X connect 11 0 13 0; +#X connect 11 0 19 0; +#X connect 12 0 23 0; +#X connect 12 0 18 0; +#X connect 13 0 14 0; +#X connect 14 0 15 0; +#X connect 15 0 10 1; +#X connect 15 0 9 1; +#X connect 16 0 4 0; +#X connect 17 0 5 0; +#X connect 18 0 13 0; +#X connect 18 0 8 0; +#X connect 19 0 21 0; +#X connect 20 0 21 0; +#X connect 21 0 23 0; +#X connect 22 0 3 0; +#X connect 23 0 3 0; +#X connect 23 0 20 0; +#X connect 24 0 3 0; +#X connect 25 0 3 0; +#X connect 26 0 3 0; diff --git a/test/toxy/tot-files.pd b/test/toxy/tot-files.pd new file mode 100644 index 0000000..b21fd41 --- /dev/null +++ b/test/toxy/tot-files.pd @@ -0,0 +1,29 @@ +#N canvas 331 164 627 378 12; +#X msg 33 336 debug; +#X msg 83 178 tot puts [concat .#0 .#1 .#9 .#: .^.c ]; +#X msg 62 143 reset \, add puts [concat .#0 .#1 .#9 .#: .^.c]; +#X msg 276 306 push a b c; +#X msg 276 335 push; +#X msg 276 277 push a b c d e f g h i j k l m n; +#X msg 100 216 write; +#X msg 113 245 read; +#X msg 171 245 read test1.tot; +#X msg 171 216 write test1.tot; +#X obj 37 51 until; +#X msg 37 22 300; +#X msg 37 86 addnext puts [concat .#0 .#1 .#2 .#3 .#4 .#5 .#6 .#7 .#8 +.#9]; +#X obj 96 336 tot . test1.tot; +#X connect 0 0 13 0; +#X connect 1 0 13 0; +#X connect 2 0 13 0; +#X connect 3 0 13 0; +#X connect 4 0 13 0; +#X connect 5 0 13 0; +#X connect 6 0 13 0; +#X connect 7 0 13 0; +#X connect 8 0 13 0; +#X connect 9 0 13 0; +#X connect 10 0 12 0; +#X connect 11 0 10 0; +#X connect 12 0 13 0; diff --git a/test/toxy/tot-head.pd b/test/toxy/tot-head.pd new file mode 100644 index 0000000..d5e5ec6 --- /dev/null +++ b/test/toxy/tot-head.pd @@ -0,0 +1,17 @@ +#N canvas 7 0 606 345 12; +#X obj 38 156 -; +#X floatatom 36 83 5 0 0 0 - - -; +#X obj 36 122 t 0 0; +#X msg 38 191 tot .^.c move head \$1 0; +#X msg 54 224 tot .^.c delete head; +#X msg 21 18 tot global margin .: set margin 3 .: .^.c create line +300 $margin 300 [expr .~y2 - .~y1 - 2 * $margin ] -tags head; +#X obj 21 264 tot .; +#X connect 0 0 3 0; +#X connect 1 0 2 0; +#X connect 2 0 0 1; +#X connect 2 1 0 0; +#X connect 3 0 6 0; +#X connect 4 0 6 0; +#X connect 5 0 6 0; +#X connect 6 3 5 0; diff --git a/test/toxy/tot-monkey.pd b/test/toxy/tot-monkey.pd new file mode 100644 index 0000000..2128ae8 --- /dev/null +++ b/test/toxy/tot-monkey.pd @@ -0,0 +1,50 @@ +#N canvas 199 254 540 290 12; +#X obj 198 62 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X msg 41 62 capture \$1; +#X obj 99 171 unpack 0 0 0; +#X floatatom 99 212 5 0 0 0 - - -; +#X floatatom 150 212 5 0 0 0 - - -; +#X floatatom 202 212 5 0 0 0 - - -; +#X obj 99 136 route motion mouseup mouse key; +#X msg 260 171 \$1; +#X obj 260 212 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 +1; +#X obj 297 208 route float; +#X msg 297 171 \$2; +#X floatatom 297 242 5 0 0 0 - - -; +#X obj 364 171 print other; +#N canvas 10 26 352 252 dux 1; +#X obj 30 20 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144 +-1 -1 0 1; +#X obj 84 19 hsl 128 15 0 127 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X text 29 222 do some editing here \, too; +#X restore 248 32 pd dux; +#N canvas 408 26 352 252 comes 1; +#X obj 30 20 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144 +-1 -1 0 1; +#X obj 84 19 hsl 128 15 0 127 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X restore 326 32 pd comes; +#X obj 41 97 tot dux; +#X obj 79 242 s pd-comes; +#X msg 121 97 1; +#X connect 0 0 1 0; +#X connect 1 0 15 0; +#X connect 2 0 3 0; +#X connect 2 1 4 0; +#X connect 2 2 5 0; +#X connect 6 0 2 0; +#X connect 6 1 2 0; +#X connect 6 2 2 0; +#X connect 6 3 7 0; +#X connect 6 3 10 0; +#X connect 6 4 12 0; +#X connect 7 0 8 0; +#X connect 9 0 11 0; +#X connect 10 0 9 0; +#X connect 15 2 16 0; +#X connect 15 2 6 0; +#X connect 15 3 17 0; +#X connect 17 0 0 0; diff --git a/test/toxy/tot-nomenu.pd b/test/toxy/tot-nomenu.pd new file mode 100644 index 0000000..f2becca --- /dev/null +++ b/test/toxy/tot-nomenu.pd @@ -0,0 +1,12 @@ +#N canvas 128 254 589 218 12; +#X obj 13 175 tot nomenu; +#N canvas 329 49 450 300 nomenu 1; +#X restore 12 16 pd nomenu; +#X msg 54 142 debug; +#X msg 13 57 tot destroy .^.m \, tot bind .^.c <Control-Key> ""; +#X msg 41 92 tot global sz .: set sz [wm maxsize .^] .: wm geometry +.^ [expr [lindex $sz 0] - 20]x[expr [lindex $sz 1] - 20]+20+20; +#X connect 0 3 3 0; +#X connect 2 0 0 0; +#X connect 3 0 0 0; +#X connect 4 0 0 0; diff --git a/test/toxy/tot-qlist.pd b/test/toxy/tot-qlist.pd new file mode 100644 index 0000000..24f7ba6 --- /dev/null +++ b/test/toxy/tot-qlist.pd @@ -0,0 +1,59 @@ +#N canvas 250 295 422 249 12; +#X obj 75 126 qlist; +#N canvas 59 33 296 202 src 1; +#X restore 15 186 pd src; +#N canvas 407 33 296 202 dst 1; +#X restore 15 216 pd dst; +#X obj 37 24 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X msg 16 126 print; +#X obj 37 89 tot src; +#X msg 139 89 rewind; +#X msg 37 54 capture \$1 pd-dst; +#X msg 271 54 read tot.ql; +#X msg 270 89 write tot.ql; +#X obj 271 20 loadbang; +#X obj 139 156 tot dst; +#X obj 209 54 t b b; +#X msg 249 126 detach; +#X msg 139 126 attach; +#X obj 332 126 r pd-dst; +#X obj 332 156 s pd-src; +#X obj 249 156 tot src; +#X obj 148 216 spigot; +#X obj 258 216 spigot; +#X obj 209 24 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X msg 216 216 0; +#X msg 197 186 1; +#X msg 307 186 1; +#X connect 0 1 14 0; +#X connect 3 0 7 0; +#X connect 4 0 0 0; +#X connect 5 2 0 0; +#X connect 6 0 0 0; +#X connect 6 0 14 0; +#X connect 7 0 5 0; +#X connect 8 0 0 0; +#X connect 9 0 0 0; +#X connect 10 0 8 0; +#X connect 11 3 22 0; +#X connect 11 3 19 0; +#X connect 12 0 0 0; +#X connect 12 1 13 0; +#X connect 13 0 11 0; +#X connect 13 0 17 0; +#X connect 14 0 11 0; +#X connect 14 0 17 0; +#X connect 15 0 16 0; +#X connect 17 3 23 0; +#X connect 17 3 18 0; +#X connect 18 0 12 0; +#X connect 18 0 21 0; +#X connect 19 0 12 0; +#X connect 19 0 21 0; +#X connect 20 0 12 0; +#X connect 21 0 18 1; +#X connect 21 0 19 1; +#X connect 22 0 18 1; +#X connect 23 0 19 1; diff --git a/test/toxy/tot-query.pd b/test/toxy/tot-query.pd new file mode 100644 index 0000000..d646f78 --- /dev/null +++ b/test/toxy/tot-query.pd @@ -0,0 +1,62 @@ +#N canvas 421 109 778 551 12; +#X msg 21 8 symbol pinecone; +#X obj 455 142 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X msg 186 8 symbol conehead; +#X obj 67 174 sel 1; +#X obj 128 238 sel 0; +#X obj 128 339 print error; +#X obj 199 238 metro 150; +#X msg 128 311 open it first...; +#X msg 54 124 tot global ch .: set ch [open ~/PureData/miXed/test/toxy/tot-query.pd +r]; +#X msg 75 435 query concat set [lsort -decreasing [glob *]]; +#X msg 37 90 reset \, addnext set x -1 .: concat set [expr acos($x)] +\, qpush; +#X msg 21 44 tot global ans .: regsub cone \$1 apple ans \, query global +ans .: concat set $ans; +#X msg 60 369 tot global ch .: set ch [open ~/.pdrc] \, query global +ch .: concat set [read $ch] \, tot global ch .: close $ch .: unset +ch; +#X msg 199 266 tot global txt ch .: set txt [gets $ch] \, query global +txt .: concat set $txt; +#N canvas 0 0 578 346 more 0; +#X msg 35 73 query .^.c bbox foo; +#X obj 19 280 print reply; +#X msg 84 152 query winfo id .^.c; +#X msg 84 231 query winfo pathname \$1; +#X msg 19 26 tot .^.c create text 400 100 -width 80 -font "times 24" +-anchor nw -text "abcd efgh ijkl mnop" -tags foo; +#X msg 48 104 tot .^.c delete foo; +#X obj 19 231 tot .; +#X obj 84 191 tot .; +#X connect 0 0 6 0; +#X connect 2 0 7 0; +#X connect 3 0 6 0; +#X connect 4 0 6 0; +#X connect 5 0 6 0; +#X connect 6 0 1 0; +#X connect 7 0 3 0; +#X restore 576 174 pd more; +#X obj 21 468 tot .; +#X obj 67 238 tot .; +#X msg 67 202 tot eval .< [global ch .: info exists ch] .>; +#X msg 21 502; +#X connect 0 0 11 0; +#X connect 1 0 3 0; +#X connect 2 0 11 0; +#X connect 3 0 17 0; +#X connect 3 1 6 0; +#X connect 4 0 7 0; +#X connect 4 1 6 0; +#X connect 6 0 13 0; +#X connect 7 0 5 0; +#X connect 8 0 15 0; +#X connect 9 0 15 0; +#X connect 10 0 15 0; +#X connect 11 0 15 0; +#X connect 12 0 15 0; +#X connect 13 0 15 0; +#X connect 15 0 18 0; +#X connect 16 1 4 0; +#X connect 17 0 16 0; diff --git a/test/toxy/tot-rstring.pd b/test/toxy/tot-rstring.pd new file mode 100644 index 0000000..24d1e1c --- /dev/null +++ b/test/toxy/tot-rstring.pd @@ -0,0 +1,15 @@ +#N canvas 254 48 671 300 12; +#X obj 21 179 tot .; +#X obj 164 77 tosymbol; +#X msg 50 77 123456; +#X msg 21 124 query set lst [list] .: foreach el [split " \$1 " ""] +.(set lst [linsert $lst 0 $el].) .: concat set [join $lst ""]; +#X msg 164 40 One Two Three; +#X msg 21 40 symbol abcdef; +#X msg 21 221; +#X connect 0 0 6 0; +#X connect 1 0 3 0; +#X connect 2 0 3 0; +#X connect 3 0 0 0; +#X connect 4 0 1 0; +#X connect 5 0 3 0; diff --git a/test/toxy/tot.ql b/test/toxy/tot.ql new file mode 100644 index 0000000..fa2b22e --- /dev/null +++ b/test/toxy/tot.ql @@ -0,0 +1,186 @@ +590.4762 pd-dst motion 70 11 0; +64.58 pd-dst text 0; +0 pd-dst motion 117 114 0; +1.45125 pd-dst motion 115 114 0; +68.2086 pd-dst motion 103 110 0; +23.22 pd-dst motion 87 106 0; +17.415 pd-dst motion 65 98 0; +23.22 pd-dst motion 53 92 0; +29.0249 pd-dst motion 47 90 0; +58.0499 pd-dst motion 47 89 0; +29.0249 pd-dst motion 47 88 0; +23.22 pd-dst motion 47 87 0; +68.345 pd-dst motion 48 87 0; +29.0249 pd-dst motion 50 87 0; +23.22 pd-dst motion 53 87 0; +17.415 pd-dst motion 59 85 0; +23.22 pd-dst motion 63 79 0; +17.415 pd-dst motion 63 78 0; +69.6599 pd-dst motion 62 78 0; +29.0249 pd-dst motion 61 76 0; +23.22 pd-dst motion 55 70 0; +17.415 pd-dst motion 49 66 0; +23.22 pd-dst motion 45 62 0; +29.0249 pd-dst motion 43 61 0; +50 pd-dst key 1 32 0; +50 pd-dst key 0 32 0; +59.773 pd-dst mouse 43 61 1 0; +76.9161 pd-dst mouseup 43 61 1; +0 pd-dst relocate 298x204+0+0 319x225+99+33; +63.8549 pd-dst motion 44 61 0; +17.415 pd-dst motion 47 61 0; +21.7687 pd-dst motion 55 63 0; +18.8662 pd-dst motion 63 65 0; +29.0249 pd-dst motion 66 65 0; +23.22 pd-dst motion 67 65 0; +451.25 pd-dst key 1 116 0; +75.4649 pd-dst key 1 101 0; +74.0136 pd-dst key 0 116 0; +47.8912 pd-dst key 1 115 0; +29.0249 pd-dst key 0 101 0; +46.4399 pd-dst key 0 115 0; +95.283 pd-dst key 1 116 0; +69.6599 pd-dst key 0 116 0; +23.22 pd-dst key 1 105 0; +75.4649 pd-dst key 1 110 0; +46.4399 pd-dst key 0 105 0; +69.6599 pd-dst key 0 110 0; +77.551 pd-dst key 1 103 0; +50.7937 pd-dst key 0 103 0; +88.934 pd-dst key 1 32 0; +75.4649 pd-dst key 0 32 0; +36.689 pd-dst key 1 116 0; +75.4649 pd-dst key 0 116 0; +69.6599 pd-dst key 1 111 0; +76.9161 pd-dst key 0 111 0; +21.7687 pd-dst key 1 116 0; +29.0249 pd-dst key 0 116 0; +48.844 pd-dst key 1 39 0; +46.4399 pd-dst key 1 115 0; +29.0249 pd-dst key 0 39 0; +52.2449 pd-dst key 0 115 0; +57.823 pd-dst key 1 32 0; +75.4649 pd-dst key 0 32 0; +88.934 pd-dst key 1 113 0; +75.4649 pd-dst key 0 113 0; +81.2698 pd-dst key 1 108 0; +75.4649 pd-dst key 1 105 0; +29.0249 pd-dst key 0 108 0; +69.6599 pd-dst key 0 105 0; +23.22 pd-dst key 1 115 0; +52.2449 pd-dst key 0 115 0; +69.6599 pd-dst key 1 116 0; +75.4649 pd-dst key 0 116 0; +70.204 pd-dst key 1 32 0; +63.8549 pd-dst key 0 32 0; +58.594 pd-dst key 1 102 0; +21.905 pd-dst key 0 102 0; +17.415 pd-dst key 1 97 0; +29.0249 pd-dst key 0 97 0; +267.029 pd-dst key 1 99 0; +52.2449 pd-dst key 0 99 0; +69.6599 pd-dst key 1 105 0; +69.6599 pd-dst key 0 105 0; +36.689 pd-dst key 1 108 0; +92.8798 pd-dst key 1 105 0; +26.1224 pd-dst key 0 108 0; +49.3424 pd-dst key 0 105 0; +75.4649 pd-dst key 1 116 0; +52.2449 pd-dst key 0 116 0; +92.8798 pd-dst key 1 121 0; +46.4399 pd-dst key 0 121 0; +399.773 pd-dst motion 67 66 0; +17.415 pd-dst motion 85 86 0; +23.22 pd-dst motion 105 102 0; +17.415 pd-dst motion 115 104 0; +69.6599 pd-dst motion 116 104 0; +21.905 pd-dst mouse 116 104 1 0; +69.6599 pd-dst mouseup 116 104 1; +280.86 pd-dst motion 117 104 0; +20.3175 pd-dst motion 129 94 0; +17.415 pd-dst motion 143 82 0; +23.22 pd-dst motion 157 72 0; +17.415 pd-dst motion 169 66 0; +29.0249 pd-dst motion 171 65 0; +72.063 pd-dst mouse 171 65 1 0; +52.2449 pd-dst motion 170 65 0; +29.0249 pd-dst motion 156 65 0; +17.415 pd-dst motion 138 65 0; +23.22 pd-dst motion 126 67 0; +17.415 pd-dst motion 116 69 0; +23.22 pd-dst motion 112 73 0; +29.0249 pd-dst motion 111 74 0; +17.415 pd-dst motion 110 76 0; +23.22 pd-dst motion 110 84 0; +17.415 pd-dst motion 110 94 0; +29.0249 pd-dst motion 112 102 0; +23.22 pd-dst motion 116 108 0; +17.415 pd-dst motion 124 112 0; +23.22 pd-dst motion 136 116 0; +29.0249 pd-dst motion 152 116 0; +17.415 pd-dst motion 170 116 0; +23.22 pd-dst motion 178 110 0; +17.415 pd-dst motion 182 100 0; +23.22 pd-dst motion 182 97 0; +29.0249 pd-dst motion 180 91 0; +17.415 pd-dst motion 177 91 0; +23.22 pd-dst motion 174 91 0; +17.415 pd-dst motion 172 90 0; +29.0249 pd-dst motion 166 88 0; +23.22 pd-dst motion 156 84 0; +17.415 pd-dst motion 148 82 0; +23.22 pd-dst motion 146 81 0; +29.0249 pd-dst motion 145 80 0; +52.2449 pd-dst motion 145 79 0; +17.415 pd-dst motion 145 65 0; +23.22 pd-dst motion 147 41 0; +17.415 pd-dst motion 147 15 0; +17.415 pd-dst motion 147 7 0; +81.2698 pd-dst motion 147 8 0; +23.22 pd-dst motion 149 14 0; +17.415 pd-dst motion 157 22 0; +29.0249 pd-dst motion 167 28 0; +23.22 pd-dst motion 175 44 0; +17.415 pd-dst motion 183 64 0; +23.22 pd-dst motion 183 80 0; +17.415 pd-dst motion 181 92 0; +29.0249 pd-dst motion 173 104 0; +23.22 pd-dst motion 163 114 0; +17.415 pd-dst motion 157 118 0; +23.22 pd-dst motion 154 118 0; +29.0249 pd-dst motion 148 120 0; +17.415 pd-dst motion 145 120 0; +23.22 pd-dst motion 139 118 0; +17.415 pd-dst motion 133 110 0; +29.0249 pd-dst motion 133 100 0; +23.22 pd-dst motion 133 86 0; +17.415 pd-dst motion 133 72 0; +23.22 pd-dst motion 133 64 0; +17.415 pd-dst motion 137 58 0; +29.0249 pd-dst motion 139 57 0; +23.22 pd-dst motion 141 56 0; +17.415 pd-dst motion 143 56 0; +23.22 pd-dst motion 151 62 0; +29.0249 pd-dst motion 157 72 0; +17.415 pd-dst motion 159 80 0; +23.22 pd-dst motion 159 88 0; +17.415 pd-dst motion 159 90 0; +29.0249 pd-dst motion 157 91 0; +23.22 pd-dst motion 156 91 0; +17.415 pd-dst motion 155 91 0; +23.22 pd-dst motion 155 89 0; +29.0249 pd-dst motion 155 88 0; +36.689 pd-dst mouseup 155 88 1; +52.2449 pd-dst motion 155 89 0; +17.415 pd-dst motion 167 101 0; +23.22 pd-dst motion 177 111 0; +29.0249 pd-dst motion 185 127 0; +17.415 pd-dst motion 187 133 0; +59.138 pd-dst mouse 187 133 1 0; +69.6599 pd-dst mouseup 187 133 1; +23.22 pd-dst motion 188 133 0; +46.4399 pd-dst motion 189 133 0; +74.15 pd-dst motion 189 134 0; +29.0249 pd-dst motion 188 136 0; +17.415 pd-dst motion 184 154 0; +23.22 pd-dst motion 178 194 0; diff --git a/test/toxy/tow-test.pd b/test/toxy/tow-test.pd new file mode 100644 index 0000000..d0a8c95 --- /dev/null +++ b/test/toxy/tow-test.pd @@ -0,0 +1,65 @@ +#N canvas 275 304 262 189 12; +#N canvas 23 43 450 305 panel 1; +#X obj 37 49 widget float f -bg orange; +#X floatatom 37 273 5 0 0 0 - - -; +#X floatatom 37 15 5 0 0 0 - - -; +#X obj 269 49 widget bang b1; +#X msg 269 15 bang; +#X obj 269 126 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 104 49 widget float f -bg orange; +#X floatatom 104 273 5 0 0 0 - - -; +#X floatatom 104 15 5 0 0 0 - - -; +#X obj 267 195 widget bang b2 -bg violet; +#X obj 267 273 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X msg 267 160 bang; +#X connect 0 0 1 0; +#X connect 2 0 0 0; +#X connect 3 0 5 0; +#X connect 4 0 3 0; +#X connect 6 0 7 0; +#X connect 8 0 6 0; +#X connect 9 0 10 0; +#X connect 11 0 9 0; +#X restore 21 32 pd panel; +#N canvas 329 98 450 310 guts 1; +#X msg 253 123 bang; +#X obj 253 279 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X msg 72 56 bang; +#X obj 136 123 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 136 88 tow panel bang b1; +#X obj 253 245 tow panel bang b2; +#X msg 280 215 debug; +#X msg 280 183 -bg violet; +#X msg 262 153 -bg white; +#X obj 29 245 tow panel float f; +#X floatatom 29 279 5 0 0 0 - - -; +#X floatatom 29 123 5 0 0 0 - - -; +#X msg 63 215 debug; +#X msg 63 183 -bg orange; +#X msg 50 153 -bg brown; +#X obj 136 21 loadbang; +#X msg 136 56 ini .^.c configure -bg darkgreen; +#X connect 0 0 5 0; +#X connect 2 0 4 0; +#X connect 4 0 3 0; +#X connect 5 0 1 0; +#X connect 6 0 5 0; +#X connect 7 0 5 0; +#X connect 8 0 5 0; +#X connect 9 0 10 0; +#X connect 11 0 9 0; +#X connect 12 0 9 0; +#X connect 13 0 9 0; +#X connect 14 0 9 0; +#X connect 15 0 16 0; +#X connect 16 0 4 0; +#X restore 120 32 pd guts; +#X obj 21 105 tow panel float f; +#X floatatom 21 139 5 0 0 0 - - -; +#X floatatom 21 72 5 0 0 0 - - -; +#X connect 2 0 3 0; +#X connect 4 0 2 0; diff --git a/toxy/Makefile b/toxy/Makefile new file mode 100644 index 0000000..fc022be --- /dev/null +++ b/toxy/Makefile @@ -0,0 +1,2 @@ +ROOT_DIR = .. +include $(ROOT_DIR)/Makefile.common diff --git a/toxy/Makefile.objects b/toxy/Makefile.objects new file mode 100644 index 0000000..d0e6476 --- /dev/null +++ b/toxy/Makefile.objects @@ -0,0 +1,22 @@ +TOT_OBJECTS = \ +common/loud.o \ +common/grow.o \ +hammer/file.o \ +hammer/gui.o \ +common/props.o \ +toxy/scriptlet.o + +TOW_OBJECTS = \ +common/loud.o \ +unstable/loader.o + +WIDGET_OBJECTS = \ +unstable/forky.o \ +common/loud.o \ +common/grow.o \ +common/dict.o \ +hammer/file.o \ +common/props.o \ +toxy/scriptlet.o + +WIDGET_PRIVATEOBJECTS = widgettype.o diff --git a/toxy/Makefile.sources b/toxy/Makefile.sources new file mode 100644 index 0000000..b0f3646 --- /dev/null +++ b/toxy/Makefile.sources @@ -0,0 +1,5 @@ +TYPES = TOT TOW WIDGET + +TOT_SOURCES = tot.c +TOW_SOURCES = tow.c +WIDGET_SOURCES = widget.c diff --git a/toxy/build_counter b/toxy/build_counter new file mode 100644 index 0000000..5774bf7 --- /dev/null +++ b/toxy/build_counter @@ -0,0 +1,3 @@ +#define TOXY_VERSION "0.1" +#define TOXY_RELEASE "alpha" +#define TOXY_BUILD 1 diff --git a/toxy/tot.c b/toxy/tot.c new file mode 100644 index 0000000..eced2b2 --- /dev/null +++ b/toxy/tot.c @@ -0,0 +1,530 @@ +/* Copyright (c) 2003 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +/* LATER handle stcriptlet's named arguments */ + +#include <stdio.h> +#include <string.h> +#include "m_pd.h" +#include "g_canvas.h" +#include "common/loud.h" +#include "hammer/file.h" +#include "hammer/gui.h" +#include "common/props.h" +#include "toxy/scriptlet.h" +#include "build_counter" + +//#define TOT_DEBUG + +/* probably much more than needed for canvas messages from gui */ +#define TOTSPY_MAXSIZE 32 + +typedef struct _tot +{ + t_object x_ob; + t_glist *x_glist; /* containing glist */ + t_symbol *x_cvremote; /* null if containing glist is our destination */ + t_symbol *x_cvname; + t_symbol *x_cvpathname; /* see tot_getpathname() */ + t_symbol *x_visedpathname; /* see tot__vised() */ + t_symbol *x_target; + int x_warned; + t_scriptlet *x_persistent; + t_scriptlet *x_transient; + t_outlet *x_out2; + t_outlet *x_out4; + t_symbol *x_defname; /* file name (if given as a creation arg) */ + t_hammerfile *x_filehandle; + t_pd *x_guidetached; + t_pd *x_guisink; + struct _totspy *x_spy; +} t_tot; + +typedef struct _totspy +{ + t_pd ts_pd; + int ts_on; + t_canvas *ts_cv; + t_symbol *ts_target; + t_symbol *ts_qsym; + double ts_lasttime; + t_symbol *ts_selector; + t_atom ts_outbuf[TOTSPY_MAXSIZE]; + t_outlet *ts_out3; +} t_totspy; + +static t_class *tot_class; +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_canvas *tot_getcanvas(t_tot *x, int complain) +{ + t_canvas *cv = 0; + t_glist *glist = + (x->x_cvremote ? + (t_glist *)pd_findbyclass(x->x_cvremote, canvas_class) : x->x_glist); + if (glist) + cv = glist_getcanvas(glist); + else if (complain) + loud_error((t_pd *)x, "bad canvas name '%s'", x->x_cvname->s_name); + if (!x->x_warned && !x->x_cvremote) + { + x->x_warned = 1; + if (!cv) cv = x->x_glist; /* redundant */ + loud_warning((t_pd *)x, "using containing canvas ('%s')", + cv->gl_name->s_name); + } + return (cv); +} + +static t_canvas *tot_cvhook(t_pd *z) +{ + return (tot_getcanvas((t_tot *)z, 1)); +} + +static t_symbol *tot_dogetpathname(t_tot *x, int visedonly, int complain) +{ + t_canvas *cv = tot_getcanvas(x, complain); + if (cv) + { + if (visedonly && !glist_isvisible(cv)) + return (0); + else if (cv == x->x_glist) + /* containing glist is our destination, and we are not in a gop */ + return (x->x_cvpathname); + else + { + char buf[32]; + sprintf(buf, ".x%x.c", (int)cv); + return (gensym(buf)); + } + } + else return (0); +} + +static t_symbol *tot_getpathname(t_tot *x, int complain) +{ + return (tot_dogetpathname(x, 0, complain)); +} + +static t_symbol *tot_getvisedpathname(t_tot *x, int complain) +{ + return (tot_dogetpathname(x, 1, complain)); +} + +static void tot_reset(t_tot *x) +{ + scriptlet_reset(x->x_persistent); +} + +static void tot_prealloc(t_tot *x, t_floatarg f) +{ + int reqsize = (int)f; + scriptlet_prealloc(x->x_persistent, reqsize, 1); + scriptlet_prealloc(x->x_transient, reqsize, 1); /* LATER rethink */ +} + +static void tot_add(t_tot *x, t_symbol *s, int ac, t_atom *av) +{ + scriptlet_add(x->x_persistent, 0, 0, ac, av); +} + +static void tot_addnext(t_tot *x, t_symbol *s, int ac, t_atom *av) +{ + scriptlet_setseparator(x->x_persistent, '\n'); + scriptlet_add(x->x_persistent, 0, 0, ac, av); +} + +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) + scriptlet_qpush(x->x_transient); + else + scriptlet_push(x->x_transient); + } +} + +static void tot_tot(t_tot *x, t_symbol *s, int ac, t_atom *av) +{ + if (ac) + { + t_scriptlet *sp = x->x_transient; + scriptlet_reset(sp); + scriptlet_add(sp, 1, 1, ac, av); + if (s == tot_ps_query) + scriptlet_qpush(sp); + else + scriptlet_push(sp); + } +} + +static void tot_dooutput(t_tot *x, t_outlet *op, + t_symbol *s, int ac, t_atom *av) +{ + if (ac == 1) + { + if (av->a_type == A_FLOAT) + outlet_float(op, av->a_w.w_float); + else if (av->a_type == A_SYMBOL) + outlet_symbol(op, av->a_w.w_symbol); + } + else if (ac) + { + if (av->a_type == A_FLOAT) + outlet_list(op, &s_list, ac, av); + else if (av->a_type == A_SYMBOL) + outlet_anything(op, av->a_w.w_symbol, ac - 1, av + 1); + } + else outlet_bang(op); +} + +static void tot__reply(t_tot *x, t_symbol *s, int ac, t_atom *av) +{ + tot_dooutput(x, ((t_object *)x)->ob_outlet, s, ac, av); +} + +static void tot__callback(t_tot *x, t_symbol *s, int ac, t_atom *av) +{ + tot_dooutput(x, x->x_out2, s, ac, av); +} + +/* LATER use properties in widgetbehavior (if gop visibility rules change) */ +static void tot_click(t_tot *x, t_floatarg xpos, t_floatarg ypos, + t_floatarg shift, t_floatarg ctrl, t_floatarg alt) +{ + int nleft; + char *head = scriptlet_getcontents(x->x_persistent, &nleft); + char buf[MAXPDSTRING + 1]; + buf[MAXPDSTRING] = 0; + hammereditor_open(x->x_filehandle, "scriptlet editor"); + while (nleft > 0) + { + if (nleft > MAXPDSTRING) + { + strncpy(buf, head, MAXPDSTRING); + head += MAXPDSTRING; + nleft -= MAXPDSTRING; + } + else + { + strncpy(buf, head, nleft); + buf[nleft] = 0; + nleft = 0; + } + hammereditor_append(x->x_filehandle, buf); + } +} + +/* This is called for all Map (f==1) and all Destroy (f==0) events, + comming from any canvas. If visedpathname is zero, we assume our + canvas does not exist. So we ignore everything, waiting for a Map + event that fits tot_getpathname(). Once we spot it, we set + visedpathname, and ignore everything, waiting for a Destroy event + that fits visedpathname. Then we clear visedpathname, etc... */ +static void tot__vised(t_tot *x, t_symbol *s, t_floatarg f) +{ + int flag = f != 0.; +#ifdef TOT_DEBUG + t_symbol *pn = tot_getpathname(x, 0); + post("tot__vised %s %g (pathname %s) ", s->s_name, f, + (pn ? pn->s_name : "unknown")); +#endif + if (!x->x_visedpathname) + { + if (flag && s == tot_getpathname(x, 0)) + { + x->x_visedpathname = s; + outlet_bang(x->x_out4); + } + } + else if (!flag && s == x->x_visedpathname) + x->x_visedpathname = 0; /* LATER reconsider reporting this */ +} + +#ifdef TOT_DEBUG +static void tot_debug(t_tot *x) +{ + t_symbol *pn = tot_getpathname(x, 0); + int sz; + char *bp; + post("containing glist: %x", x->x_glist); + post("destination: %s", x->x_cvname->s_name); + post("pathname%s %s", (pn ? ":" : ""), (pn ? pn->s_name : "unknown")); + bp = scriptlet_getbuffer(x->x_transient, &sz); + post("transient buffer (size %d):\n\"%s\"", sz, bp); + bp = scriptlet_getbuffer(x->x_persistent, &sz); + post("persistent buffer (size %d):\n\"%s\"", sz, bp); +} +#endif + +static void tot_readhook(t_pd *z, t_symbol *fn, int ac, t_atom *av) +{ + scriptlet_read(((t_tot *)z)->x_persistent, fn); +} + +static void tot_writehook(t_pd *z, t_symbol *fn, int ac, t_atom *av) +{ + scriptlet_write(((t_tot *)z)->x_persistent, fn); +} + +static void tot_read(t_tot *x, t_symbol *s) +{ + if (s && s != &s_) + scriptlet_read(x->x_persistent, s); + else + hammerpanel_open(x->x_filehandle, 0); +} + +static void tot_write(t_tot *x, t_symbol *s) +{ + if (s && s != &s_) + scriptlet_write(x->x_persistent, s); + else + hammerpanel_save(x->x_filehandle, + canvas_getdir(x->x_glist), x->x_defname); +} + +static void tot_detach(t_tot *x) +{ + t_canvas *cv = tot_getcanvas(x, 1); + if (cv && glist_isvisible(cv)) + { + t_pd *gc; + t_symbol *target; + char buf[64]; + sprintf(buf, ".x%x", (int)cv); + target = gensym(buf); + if (!tot_guiconnect_class) + { + gc = (t_pd *)guiconnect_new(0, gensym("tot")); + tot_guiconnect_class = *gc; + typedmess(gc, gensym("signoff"), 0, 0); + } + if (gc = pd_findbyclass(target, tot_guiconnect_class)) + { + x->x_guidetached = gc; + pd_unbind(gc, target); + pd_bind(x->x_guisink, target); + } + } +} + +static void tot_attach(t_tot *x) +{ + t_canvas *cv = tot_getcanvas(x, 1); + if (cv && glist_isvisible(cv) && x->x_guidetached) + { + if (tot_guiconnect_class) + { + t_pd *gc; + t_symbol *target; + char buf[64]; + sprintf(buf, ".x%x", (int)cv); + target = gensym(buf); + if (gc = pd_findbyclass(target, tot_guiconnect_class)) + { + } + else + { /* assuming nobody else detached it in the meantime... */ + pd_unbind(x->x_guisink, target); + pd_bind(x->x_guidetached, target); + x->x_guidetached = 0; + } + } + else bug("tot_attach"); + } +} + +static void tot_capture(t_tot *x, t_symbol *s, t_floatarg f) +{ + t_totspy *ts = x->x_spy; + if ((int)f) + { + t_canvas *cv = tot_getcanvas(x, 1); + ts->ts_qsym = (s == &s_ ? 0 : s); + if (cv != ts->ts_cv) + { + if (ts->ts_target) + { + pd_unbind((t_pd *)ts, ts->ts_target); + ts->ts_cv = 0; + ts->ts_target = 0; + } + if (cv) + { + char buf[64]; + ts->ts_cv = cv; + sprintf(buf, ".x%x", (int)cv); + pd_bind((t_pd *)ts, ts->ts_target = gensym(buf)); + } + } + ts->ts_on = (ts->ts_target != 0); + if (ts->ts_on && ts->ts_qsym) + { + ts->ts_lasttime = clock_getlogicaltime(); + ts->ts_selector = gensym("add"); + SETFLOAT(&ts->ts_outbuf[0], 0); + SETSYMBOL(&ts->ts_outbuf[1], ts->ts_qsym); + SETSYMBOL(&ts->ts_outbuf[2], &s_); + outlet_anything(ts->ts_out3, gensym("clear"), 0, 0); + } + } + else ts->ts_on = 0; +} + +static void totspy_anything(t_totspy *ts, t_symbol *s, int ac, t_atom *av) +{ + if (ts->ts_on) + { + if (ts->ts_qsym) + { + int cnt = ac + 3; + if (cnt < TOTSPY_MAXSIZE) + { + t_atom *ap = ts->ts_outbuf; + ap++->a_w.w_float = (float)clock_gettimesince(ts->ts_lasttime); + ap++; + ap++->a_w.w_symbol = s; + while (ac--) *ap++ = *av++; + outlet_anything(ts->ts_out3, + ts->ts_selector, cnt, ts->ts_outbuf); + ts->ts_lasttime = clock_getlogicaltime(); + } + else loud_warning((t_pd *)ts, + "unexpectedly long message (\"%s...\"), ignored", + s->s_name); + } + else outlet_anything(ts->ts_out3, s, ac, av); + } +} + +static void totsink_anything(t_pd *x, t_symbol *s, int ac, t_atom *av) +{ + /* nop */ +} + +static void tot_free(t_tot *x) +{ + pd_unbind((t_pd *)x, x->x_target); + hammergui_unbindvised((t_pd *)x); + hammerfile_free(x->x_filehandle); + scriptlet_free(x->x_persistent); + scriptlet_free(x->x_transient); + if (x->x_spy->ts_target) + pd_unbind((t_pd *)x->x_spy, x->x_spy->ts_target); + pd_free((t_pd *)x->x_spy); + pd_free(x->x_guisink); +} + +static void *tot_new(t_symbol *s1, t_symbol *s2) +{ + t_tot *x = (t_tot *)pd_new(tot_class); + char buf[64]; + sprintf(buf, "tot%x", (int)x); + pd_bind((t_pd *)x, x->x_target = gensym(buf)); + x->x_transient = + scriptlet_new((t_pd *)x, x->x_target, x->x_target, 0, tot_cvhook); + x->x_persistent = + scriptlet_new((t_pd *)x, x->x_target, x->x_target, 0, tot_cvhook); + x->x_glist = canvas_getcurrent(); + if (s1 && s1 != &s_ && strcmp(s1->s_name, ".")) + { + x->x_cvremote = canvas_makebindsym(x->x_cvname = s1); + x->x_cvpathname = 0; + } + else + { + x->x_warned = (s1 && *s1->s_name == '.'); /* do not warn if explicit */ + x->x_cvremote = 0; + x->x_cvname = x->x_glist->gl_name; + sprintf(buf, ".x%x.c", (int)x->x_glist); + x->x_cvpathname = gensym(buf); + } + outlet_new((t_object *)x, &s_anything); + x->x_out2 = outlet_new((t_object *)x, &s_anything); + x->x_spy = (t_totspy *)pd_new(totspy_class); + x->x_spy->ts_on = 0; + x->x_spy->ts_cv = 0; + x->x_spy->ts_target = 0; + x->x_spy->ts_qsym = 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_) + { + x->x_defname = s2; + scriptlet_read(x->x_persistent, s2); + } + else x->x_defname = &s_; + x->x_filehandle = hammerfile_new((t_pd *)x, 0, + tot_readhook, tot_writehook, 0); + hammergui_bindvised((t_pd *)x); + x->x_visedpathname = tot_getvisedpathname(x, 0); + x->x_guidetached = 0; + x->x_guisink = pd_new(totsink_class); + return (x); +} + +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"); + tot_class = class_new(gensym("tot"), + (t_newmethod)tot_new, + (t_method)tot_free, + sizeof(t_tot), 0, A_DEFSYM, A_DEFSYM, 0); + class_addmethod(tot_class, (t_method)tot_prealloc, + gensym("prealloc"), A_FLOAT, 0); + class_addmethod(tot_class, (t_method)tot_read, + gensym("read"), A_DEFSYM, 0); + class_addmethod(tot_class, (t_method)tot_write, + gensym("write"), A_DEFSYM, 0); + class_addmethod(tot_class, (t_method)tot_reset, + gensym("reset"), 0); + class_addmethod(tot_class, (t_method)tot_push, + gensym("push"), A_GIMME, 0); + class_addmethod(tot_class, (t_method)tot_push, + gensym("qpush"), A_GIMME, 0); + class_addmethod(tot_class, (t_method)tot_add, + gensym("add"), A_GIMME, 0); + class_addmethod(tot_class, (t_method)tot_addnext, + gensym("addnext"), A_GIMME, 0); + class_addmethod(tot_class, (t_method)tot_tot, + gensym("tot"), A_GIMME, 0); + class_addmethod(tot_class, (t_method)tot_tot, + gensym("query"), A_GIMME, 0); + class_addmethod(tot_class, (t_method)tot_detach, + gensym("detach"), 0); + class_addmethod(tot_class, (t_method)tot_attach, + 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__reply, + gensym("_rp"), A_GIMME, 0); + class_addmethod(tot_class, (t_method)tot__callback, + gensym("_cb"), A_GIMME, 0); + class_addmethod(tot_class, (t_method)tot_click, + gensym("click"), + A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); + class_addmethod(tot_class, (t_method)tot__vised, + gensym("_vised"), A_SYMBOL, A_FLOAT, 0); +#ifdef TOT_DEBUG + class_addmethod(tot_class, (t_method)tot_debug, + gensym("debug"), 0); +#endif + hammerfile_setup(tot_class, 0); + totspy_class = class_new(gensym("tot spy"), 0, 0, + sizeof(t_totspy), CLASS_PD, 0); + class_addanything(totspy_class, totspy_anything); + totsink_class = class_new(gensym("tot sink"), 0, 0, + sizeof(t_pd), CLASS_PD, 0); + class_addanything(totsink_class, totsink_anything); +} diff --git a/toxy/tow.c b/toxy/tow.c new file mode 100644 index 0000000..5e4f902 --- /dev/null +++ b/toxy/tow.c @@ -0,0 +1,26 @@ +/* Copyright (c) 2003 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +/* The tow extern just loads the 'widget' library. + The tow class itself is defined in widget.c. */ + +#include "m_pd.h" +#include "common/loud.h" +#include "unstable/loader.h" + +void tow_setup(void) +{ + int result = LOADER_OK; + if (zgetfn(&pd_objectmaker, gensym("widget"))) + loud_warning(0, "widget is already loaded"); + else + result = unstable_load_lib("", "widget"); + if (result == LOADER_NOFILE) + loud_error(0, "widget library is missing"); + else if (!zgetfn(&pd_objectmaker, gensym("widget"))) + { + loud_error(0, "version mismatch"); + loud_errand(0, "use a more recent Pd release (or recompile toxy)."); + } +} diff --git a/toxy/toxy-all.exclude b/toxy/toxy-all.exclude new file mode 100644 index 0000000..d9e9df1 --- /dev/null +++ b/toxy/toxy-all.exclude @@ -0,0 +1,8 @@ +*~ +*.o +*.gz +*.html +*.out +ref +ref/* +dumpsetups diff --git a/toxy/toxy-shared.include b/toxy/toxy-shared.include new file mode 100644 index 0000000..e754469 --- /dev/null +++ b/toxy/toxy-shared.include @@ -0,0 +1,19 @@ +shared/common/loud.c +shared/common/loud.h +shared/common/grow.c +shared/common/grow.h +shared/common/dict.c +shared/common/dict.h +shared/hammer/file.c +shared/hammer/file.h +shared/hammer/gui.c +shared/hammer/gui.h +shared/unstable/forky.c +shared/unstable/forky.h +shared/unstable/loader.c +shared/unstable/loader.h +shared/unstable/pd_imp.h +shared/common/props.c +shared/common/props.h +shared/toxy/scriptlet.c +shared/toxy/scriptlet.h diff --git a/toxy/toxy-test.exclude b/toxy/toxy-test.exclude new file mode 100644 index 0000000..6b3cc43 --- /dev/null +++ b/toxy/toxy-test.exclude @@ -0,0 +1,5 @@ +*~ +import-result.pd +import-debug.pd +temporary +temporary/* diff --git a/toxy/toxy-vicious.exclude b/toxy/toxy-vicious.exclude new file mode 100644 index 0000000..5e5a82e --- /dev/null +++ b/toxy/toxy-vicious.exclude @@ -0,0 +1,3 @@ +*~ +old +old/* diff --git a/toxy/widget.c b/toxy/widget.c new file mode 100644 index 0000000..aff5e32 --- /dev/null +++ b/toxy/widget.c @@ -0,0 +1,1146 @@ +/* Copyright (c) 2003 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * 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> +#include "m_pd.h" +#include "g_canvas.h" +#include "common/loud.h" +#include "common/grow.h" +#include "unstable/forky.h" +#include "hammer/file.h" +#include "common/props.h" +#include "toxy/scriptlet.h" +#include "widgettype.h" +#include "build_counter" + +/* our proxy of the text_class (not in the API), LATER do not cheat */ +static t_class *makeshift_class; + +//#define WIDGET_DEBUG +//#define TOW_DEBUG + +enum { WIDGET_NOUPDATE = 0, WIDGET_RECONFIG, WIDGET_REVIS }; + +typedef struct _towentry +{ + struct _tow *te_tow; + struct _towentry *te_next; +} t_towentry; + +typedef struct _widgetentry +{ + struct _widget *we_widget; + struct _widgetentry *we_next; +} t_widgetentry; + +typedef struct _widget +{ + t_object x_ob; + t_glist *x_glist; /* containing glist */ + t_widgettype *x_typedef; + t_symbol *x_type; /* 1st creation arg: our type */ + t_symbol *x_tkclass; /* Tk widget class */ + t_symbol *x_name; /* 2nd creation arg: our name (common tag) */ + 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_props *x_options; /* instance options */ + t_props *x_handlers; /* instance handlers */ + t_props *x_arguments; /* instance arguments */ + t_scriptlet *x_iniscript; /* instance initializer */ + t_scriptlet *x_optscript; /* option scriptlet */ + t_scriptlet *x_auxscript; /* auxiliary scriptlet */ + t_scriptlet *x_transient; /* output buffer */ + t_hammerfile *x_filehandle; + int x_width; + int x_height; + t_symbol *x_background; + int x_hasstate; + int x_update; /* see widget_update() */ + int x_selected; + int x_disabled; + t_clock *x_transclock; + t_towentry *x_towlist; +} t_widget; + +typedef struct _tow +{ + t_object x_ob; + t_glist *x_glist; /* containing glist */ + t_symbol *x_cvremote; /* null if containing glist is our destination */ + t_symbol *x_cvname; + t_symbol *x_type; /* 2nd creation arg: widget's type */ + t_symbol *x_name; /* 3rd creation arg: widget's name */ + t_widgettype *x_typedef; + t_widgetentry *x_widgetlist; + struct _tow *x_next; /* next in the global towlist */ +} t_tow; + +static t_class *widget_class; +static t_class *tow_class; + +/* Global towlist, searched in widget_attach(). There is no global widgetlist, + because a destination glist is searched instead in tow_attach(). */ +static t_tow *towlist = 0; + +static char *widget_propsresolver(t_pd *z, int ac, t_atom *av) +{ + t_widget *x = (t_widget *)z; + int len; + scriptlet_reset(x->x_auxscript); + if (scriptlet_add(x->x_auxscript, 1, 0, ac, av)) + return (scriptlet_getcontents(x->x_auxscript, &len)); + else + return (0); +} + +static t_canvas *widget_cvhook(t_pd *z) +{ + return (glist_getcanvas(((t_widget *)z)->x_glist)); +} + +/* LATER move to scriptlet.c, use the scriptlet interface (.^) */ +static t_symbol *widget_getcvpathname(t_widget *x, t_glist *glist) +{ + t_canvas *cv; + if (glist && glist != x->x_glist) + { + bug("widget_getcvpathname"); + x->x_glist = glist; + } + cv = glist_getcanvas(x->x_glist); + if (cv == x->x_glist) + return (x->x_cvpathname); /* we are not in a gop */ + else + { + char buf[32]; + sprintf(buf, ".x%x.c", (int)cv); + return (gensym(buf)); + } +} + +/* LATER use the scriptlet interface (.-) */ +static t_symbol *widget_getmypathname(t_widget *x, t_glist *glist) +{ + char buf[64]; + t_symbol *cvpathname = widget_getcvpathname(x, glist); + sprintf(buf, "%s.%s%x", cvpathname->s_name, x->x_name->s_name, (int)x); + return (gensym(buf)); +} + +static void widget_postatoms(char *msg, int ac, t_atom *av) +{ + startpost(msg); + while (ac--) + { + if (av->a_type == A_FLOAT) + postfloat(av->a_w.w_float); + else if (av->a_type == A_SYMBOL) + poststring(av->a_w.w_symbol->s_name); + av++; + } + endpost(); +} + +static void widget_transtick(t_widget *x) +{ + glist_delete(x->x_glist, (t_gobj *)x); +} + +/* called from widget__failure(), LATER also bind this to F4 or something */ +static void widget_transedit(t_widget *x) +{ + t_text *newt, *oldt = (t_text *)x; + t_binbuf *bb = binbuf_new(); + int nopt, nbnd, narg; + t_atom *opt = props_getall(x->x_options, &nopt); + t_atom *bnd = props_getall(x->x_handlers, &nbnd); + t_atom *arg = props_getall(x->x_arguments, &narg); + binbuf_addv(bb, "sss", gensym("widget"), x->x_type, x->x_name); + if (narg) binbuf_add(bb, narg, arg); + if (nopt) binbuf_add(bb, nopt, opt); + if (nbnd) binbuf_add(bb, nbnd, bnd); + canvas_setcurrent(x->x_glist); + newt = (t_text *)pd_new(makeshift_class); + newt->te_width = 0; + newt->te_type = T_OBJECT; + newt->te_binbuf = bb; + newt->te_xpix = oldt->te_xpix; + newt->te_ypix = oldt->te_ypix; + glist_add(x->x_glist, &newt->te_g); + glist_noselect(x->x_glist); + glist_select(x->x_glist, &newt->te_g); + gobj_activate(&newt->te_g, x->x_glist, 1); + x->x_glist->gl_editor->e_textdirty = 1; /* force evaluation */ + canvas_unsetcurrent(x->x_glist); + canvas_dirty(x->x_glist, 1); + clock_delay(x->x_transclock, 0); /* LATER rethink */ +} + +/* FIXME x_glist field validation against glist parameter (all handlers) */ + +static void widget_getrect(t_gobj *z, t_glist *glist, + int *xp1, int *yp1, int *xp2, int *yp2) +{ + t_widget *x = (t_widget *)z; + float x1, y1, x2, y2; + x1 = text_xpix((t_text *)x, glist); + y1 = text_ypix((t_text *)x, glist); + x2 = x1 + x->x_width; + y2 = y1 + x->x_height; + *xp1 = x1; + *yp1 = y1; + *xp2 = x2; + *yp2 = y2; +} + +static void widget_displace(t_gobj *z, t_glist *glist, int dx, int dy) +{ + t_widget *x = (t_widget *)z; + t_text *t = (t_text *)z; + t->te_xpix += dx; + t->te_ypix += dy; + if (glist_isvisible(glist)) + sys_vgui("%s move %s %d %d\n", widget_getcvpathname(x, glist)->s_name, + x->x_cbtarget->s_name, dx, dy); + canvas_fixlinesfor(glist_getcanvas(glist), t); +} + +static void widget_select(t_gobj *z, t_glist *glist, int state) +{ + t_widget *x = (t_widget *)z; + char *mypathname = widget_getmypathname(x, glist)->s_name; + if (state) + { + sys_vgui("%s config -bg blue %s\n", mypathname, + (x->x_hasstate ? "-state disabled" : "")); + x->x_selected = 1; + } + else + { + if (x->x_disabled) + sys_vgui("%s config -bg %s\n", mypathname, + (x->x_background ? x->x_background->s_name : "gray")); + else + sys_vgui("%s config -bg %s\n", mypathname, + (x->x_background ? x->x_background->s_name : "gray"), + (x->x_hasstate ? "-state normal" : "")); + x->x_selected = 0; + } +} + +static void widget_delete(t_gobj *z, t_glist *glist) +{ + canvas_deletelinesfor(glist, (t_text *)z); +} + +static void widget_pushoptions(t_widget *x) +{ + char *mypathname = widget_getmypathname(x, x->x_glist)->s_name; + if (scriptlet_evaluate(x->x_optscript, x->x_transient, 0, 0, 0, 0)) + { +#ifdef WIDGET_DEBUG + int sz; + 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"); */ + } +} + +static void widget_pushinits(t_widget *x) +{ + if (masterwidget_evaluate(x->x_transient, 0, 0, 0, x->x_arguments)) + scriptlet_push(x->x_transient); + else + bug("widget_pushinits (master)"); + if (widgettype_isdefined(x->x_typedef)) + { + 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)"); */ + } + } + 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)"); */ + } +} + +static void widget_vis(t_gobj *z, t_glist *glist, int vis) +{ + t_widget *x = (t_widget *)z; + t_text *t = (t_text *)z; + char *cvpathname = widget_getcvpathname(x, glist)->s_name; + char *mypathname = widget_getmypathname(x, glist)->s_name; + x->x_update = WIDGET_NOUPDATE; + if (vis) + { + float px1 = text_xpix((t_text *)x, glist); + float py1 = text_ypix((t_text *)x, glist); +#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_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"); + } + else + { +#ifndef PD_MINOR_VERSION + t_rtext *rt = glist_findrtext(glist, t); + if (rt) rtext_free(rt); +#endif + sys_vgui("destroy %s\n", mypathname); + } +} + +static void widget_save(t_gobj *z, t_binbuf *bb) +{ + t_widget *x = (t_widget *)z; + t_text *t = (t_text *)x; + int nopt, nbnd, narg; + t_atom *opt = props_getall(x->x_options, &nopt); + t_atom *bnd = props_getall(x->x_handlers, &nbnd); + t_atom *arg = props_getall(x->x_arguments, &narg); + binbuf_addv(bb, "ssiisss", gensym("#X"), gensym("obj"), + (int)t->te_xpix, (int)t->te_ypix, gensym("widget"), + x->x_type, x->x_name); + if (narg) binbuf_add(bb, narg, arg); + if (nopt) binbuf_add(bb, nopt, opt); + if (nbnd) binbuf_add(bb, nbnd, bnd); + binbuf_addsemi(bb); +} + +/* FIXME */ +static void widget_properties(t_gobj *z, t_glist *glist) +{ + t_widget *x = (t_widget *)z; + t_atom *ap; + int ac, nleft; + char *head = scriptlet_getcontents(x->x_optscript, &nleft); + char buf[MAXPDSTRING + 1]; + buf[MAXPDSTRING] = 0; + sprintf(buf, "%s %s", x->x_type->s_name, x->x_name->s_name); + hammereditor_open(x->x_filehandle, buf); + while (nleft > 0) + { + if (nleft > MAXPDSTRING) + { + strncpy(buf, head, MAXPDSTRING); + head += MAXPDSTRING; + nleft -= MAXPDSTRING; + } + else + { + strncpy(buf, head, nleft); + buf[nleft] = 0; + nleft = 0; + } + hammereditor_append(x->x_filehandle, buf); + } + scriptlet_reset(x->x_auxscript); + ap = props_getall(x->x_handlers, &ac); + if (ac) scriptlet_add(x->x_auxscript, 0, 0, ac, ap); + head = scriptlet_getcontents(x->x_auxscript, &nleft); + hammereditor_append(x->x_filehandle, "\n"); + while (nleft > 0) + { + if (nleft > MAXPDSTRING) + { + strncpy(buf, head, MAXPDSTRING); + head += MAXPDSTRING; + nleft -= MAXPDSTRING; + } + else + { + strncpy(buf, head, nleft); + buf[nleft] = 0; + nleft = 0; + } + hammereditor_append(x->x_filehandle, buf); + } +} + +static t_widgetbehavior widget_behavior = +{ + widget_getrect, + widget_displace, + widget_select, + 0, + widget_delete, + widget_vis, + 0, + FORKY_WIDGETPADDING +}; + +static void widget_update(t_widget *x) +{ + t_atom *ap; + int ac; + scriptlet_reset(x->x_optscript); + ap = props_getall(widgettype_getoptions(x->x_typedef), &ac); + if (ac) scriptlet_add(x->x_optscript, 0, 0, ac, ap); + ap = props_getall(x->x_options, &ac); + if (ac) scriptlet_add(x->x_optscript, 0, 0, ac, ap); + if (x->x_update && + glist_isvisible(x->x_glist)) /* FIXME the condition */ + { + if (x->x_update == WIDGET_REVIS) + { + widget_vis((t_gobj *)x, x->x_glist, 0); + widget_vis((t_gobj *)x, x->x_glist, 1); + } + else widget_pushoptions(x); + x->x_update = WIDGET_NOUPDATE; + } + /* LATER cache handlers */ +} + +static t_symbol *widget_addprops(t_widget *x, t_props *op, + t_symbol *s, int ac, t_atom *av) +{ + if (op) + { + t_symbol *empty; + empty = props_add(op, s, ac, av); + if (empty) + loud_error((t_pd *)x, "no value given for %s '%s'", + props_getname(op), empty->s_name); + widget_update(x); + return (empty); + } + else + { + bug("widget_addprops"); + return (0); + } +} + +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); + return (empty); +} + +static void widget_anything(t_widget *x, t_symbol *s, int ac, t_atom *av) +{ + if (s && s != &s_) + { + if (*s->s_name == '-' || *s->s_name == '@' || *s->s_name == '#') + { + t_symbol *empty; + x->x_update = WIDGET_RECONFIG; + if (empty = widget_addmessage(x, s, ac, av)) + loud_errand((t_pd *)x, + "(use 'remove %s' if that is what you want).", + empty->s_name); + } + else + { + /* LATER cache this */ + int hlen; + t_atom *hp; + t_symbol *sel; + char buf[MAXPDSTRING]; + buf[0] = '@'; + strcpy(buf + 1, s->s_name); + sel = gensym(buf); + if (((hp = props_getone(x->x_handlers, sel, &hlen)) || + (hp = props_getone(widgettype_gethandlers(x->x_typedef), + sel, &hlen))) + && hlen > 1) + { + scriptlet_reset(x->x_auxscript); + scriptlet_add(x->x_auxscript, 0, 0, hlen - 1, hp + 1); + if (scriptlet_evaluate(x->x_auxscript, x->x_transient, + 1, ac, av, 0)) + scriptlet_push(x->x_transient); + } + else loud_nomethod((t_pd *)x, s); + } + } +} + +/* LATER cache this */ +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 (ac > 1) + { + scriptlet_reset(x->x_transient); + scriptlet_add(x->x_transient, 1, 1, ac - 1, av + 1); + scriptlet_push(x->x_transient); + } + } +} + +/* LATER cache this */ +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 (ac > 1) + { + t_atom at; + SETFLOAT(&at, f); + scriptlet_reset(x->x_auxscript); + scriptlet_add(x->x_auxscript, 0, 0, ac - 1, av + 1); + if (scriptlet_evaluate(x->x_auxscript, + x->x_transient, 1, 1, &at, 0)) + scriptlet_push(x->x_transient); + } + } +} + +/* LATER cache this */ +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 (ac > 1) + { + t_atom at; + SETSYMBOL(&at, s); + scriptlet_reset(x->x_auxscript); + scriptlet_add(x->x_auxscript, 0, 0, ac - 1, av + 1); + if (scriptlet_evaluate(x->x_auxscript, + x->x_transient, 1, 1, &at, 0)) + scriptlet_push(x->x_transient); + } + } +} + +static void widget_remove(t_widget *x, t_symbol *s) +{ + if (s) + { + t_props *op; + if (*s->s_name == '-') + op = x->x_options; + else if (*s->s_name == '@') + op = x->x_handlers; + else if (*s->s_name == '#') + op = x->x_arguments; + else + op = 0; + if (op && props_remove(op, s)) + { + x->x_update = WIDGET_REVIS; + widget_update(x); + } + else loud_warning((t_pd *)x, "%s %s has not been specified", + props_getname(op), s->s_name); + } +} + +static void widget_ini(t_widget *x, t_symbol *s, int ac, t_atom *av) +{ + if (ac) + { + scriptlet_reset(x->x_iniscript); + scriptlet_add(x->x_iniscript, 0, 0, ac, av); + } +} +static void widget_tot(t_widget *x, t_symbol *s, int ac, t_atom *av) +{ + if (ac) + { + t_scriptlet *sp = x->x_transient; + scriptlet_reset(sp); + scriptlet_add(sp, 1, 1, ac, av); + scriptlet_push(sp); + } +} + +static void widget_refresh(t_widget *x) +{ + x->x_update = WIDGET_REVIS; + widget_update(x); +} + +static void widget__failure(t_widget *x) +{ + /* LATER pass error message from gui, and report here */ + loud_error((t_pd *)x, "creation failure"); + widget_transedit(x); +} + +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); +#endif + x->x_width = (int)fw; + x->x_height = (int)fh; + if (bg != &s_) x->x_background = bg; + x->x_hasstate = ((int)fst == 0); + canvas_fixlinesfor(glist_getcanvas(x->x_glist), (t_text *)x); /* FIXME */ +} + +static void widget__callback(t_widget *x, t_symbol *s, int ac, t_atom *av) +{ + if (ac == 1) + { + if (av->a_type == A_FLOAT) + outlet_float(((t_object *)x)->ob_outlet, av->a_w.w_float); + else if (av->a_type == A_SYMBOL) + outlet_symbol(((t_object *)x)->ob_outlet, av->a_w.w_symbol); + } + else if (ac) + { + if (av->a_type == A_FLOAT) + outlet_list(((t_object *)x)->ob_outlet, &s_list, ac, av); + else if (av->a_type == A_SYMBOL) + outlet_anything(((t_object *)x)->ob_outlet, + av->a_w.w_symbol, ac - 1, av + 1); + } + else outlet_bang(((t_object *)x)->ob_outlet); +} + +/* FIXME this is a hack (see also widget_select) */ +/* FIXME why <Leave> is being issued on button press? */ +static void widget__inout(t_widget *x, t_floatarg f) +{ + if (x->x_disabled) + { + if (!x->x_glist->gl_edit) + { + if (!x->x_selected) + { + char *mypathname = widget_getmypathname(x, x->x_glist)->s_name; + if (x->x_hasstate) + sys_vgui("%s config -state normal\n", mypathname); + } + x->x_disabled = 0; + } + } + else if ((int)f && x->x_glist->gl_edit) + { + char *mypathname = widget_getmypathname(x, x->x_glist)->s_name; + if (x->x_hasstate) + sys_vgui("%s config -state disabled\n", mypathname); + x->x_disabled = 1; + } +} + +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.); +} + +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); +} + +int widget_iswidget(t_gobj *g, t_symbol *type, t_symbol *name) +{ + if (*(t_pd *)g == widget_class) + { + t_widget *x = (t_widget *)g; + return ((!type || type == x->x_type) && + (!name || name == x->x_name)); + } + else return (0); +} + +#ifdef WIDGET_DEBUG +static void widget_debug(t_widget *x) +{ + t_symbol *pn = widget_getcvpathname(x, 0); + t_symbol *mn = widget_getmypathname(x, 0); + int sz, i, nopt; + t_atom *ap; + char *bp, *key; + post("containing glist: %x", x->x_glist); + post("cv pathname%s %s", (pn ? ":" : ""), (pn ? pn->s_name : "unknown")); + post("my pathname%s %s", (mn ? ":" : ""), (mn ? mn->s_name : "unknown")); + if (ap = props_getall(widgettype_getoptions(x->x_typedef), &nopt)) + widget_postatoms("default options:", nopt, ap); + if (ap = props_getall(x->x_options, &nopt)) + widget_postatoms("instance options:", nopt, ap); + if (ap = props_getall(widgettype_gethandlers(x->x_typedef), &nopt)) + widget_postatoms("default handlers:", nopt, ap); + if (ap = props_getall(x->x_handlers, &nopt)) + widget_postatoms("instance handlers:", nopt, ap); + if (ap = props_getall(widgettype_getarguments(x->x_typedef), &nopt)) + widget_postatoms("default arguments:", nopt, ap); + if (ap = props_getall(x->x_arguments, &nopt)) + widget_postatoms("instance arguments:", nopt, ap); + post("dictionary:"); + bp = props_firstvalue(x->x_arguments, &key); + while (bp) + { + post("\t%s: \"%s\"", key, bp); + bp = props_nextvalue(x->x_arguments, &key); + } + bp = scriptlet_getcontents(x->x_transient, &sz); + post("transient buffer (size %d):\n\"%s\"", sz, bp); + bp = scriptlet_getcontents(x->x_optscript, &sz); + post("option buffer (size %d):\n\"%s\"", sz, bp); + bp = widgettype_getcontents(x->x_typedef, &sz); + post("type initializer (size %d):\n\"%s\"", sz, bp); + bp = scriptlet_getcontents(x->x_iniscript, &sz); + post("instance initializer (size %d):\n\"%s\"", sz, bp); +} +#endif + +static void widget_attach(t_widget *x); +static void widget_detach(t_widget *x); + +static void widget_free(t_widget *x) +{ + pd_unbind((t_pd *)x, x->x_cbtarget); + pd_unbind((t_pd *)x, x->x_rptarget); + props_freeall(x->x_options); + scriptlet_free(x->x_iniscript); + scriptlet_free(x->x_optscript); + scriptlet_free(x->x_auxscript); + scriptlet_free(x->x_transient); + hammerfile_free(x->x_filehandle); + if (x->x_transclock) clock_free(x->x_transclock); + widget_detach(x); +} + +static void *widget_new(t_symbol *s, int ac, t_atom *av) +{ + t_widget *x = (t_widget *)pd_new(widget_class); + char buf[MAXPDSTRING]; + masterwidget_initialize(); + x->x_type = 0; + x->x_name = 0; + if (ac && av->a_type == A_SYMBOL) + { + x->x_type = av->a_w.w_symbol; + ac--; av++; + } + if (ac && av->a_type == A_SYMBOL) + { + x->x_name = av->a_w.w_symbol; + ac--; av++; + } + /* LATER think about anonymous widgets (single arg, or '.') */ + if (!x->x_type || x->x_type == &s_ || + !x->x_name || x->x_name == &s_) + { + loud_error((t_pd *)x, "bad arguments for a widget"); + loud_errand((t_pd *)x, + "expecting \"widget <type> <name> [properties]\""); + return (0); + } + sprintf(buf, "%s%x", x->x_name->s_name, (int)x); + pd_bind((t_pd *)x, x->x_cbtarget = gensym(buf)); + sprintf(buf, "%s%x.rp", x->x_name->s_name, (int)x); + pd_bind((t_pd *)x, x->x_rptarget = gensym(buf)); + + x->x_typedef = widgettype_get(x->x_type); + if (!(x->x_tkclass = widgettype_tkclass(x->x_typedef))) + x->x_tkclass = x->x_type; + + x->x_iniscript = scriptlet_new((t_pd *)x, x->x_rptarget, x->x_cbtarget, + x->x_name, widget_cvhook); + x->x_optscript = scriptlet_new((t_pd *)x, x->x_rptarget, x->x_cbtarget, + x->x_name, widget_cvhook); + x->x_auxscript = scriptlet_new((t_pd *)x, x->x_rptarget, x->x_cbtarget, + x->x_name, widget_cvhook); + x->x_transient = scriptlet_new((t_pd *)x, x->x_rptarget, x->x_cbtarget, + x->x_name, widget_cvhook); + + x->x_options = props_new((t_pd *)x, "option", "-", 0, 0); + x->x_handlers = props_new((t_pd *)x, "handler", "@", x->x_options, 0); + x->x_arguments = props_new((t_pd *)x, "argument", "#", x->x_options, + widget_propsresolver); + + sprintf(buf, ".^.c.%s%x", x->x_name->s_name, (int)x); + x->x_glist = canvas_getcurrent(); + sprintf(buf, ".x%x.c", (int)x->x_glist); + x->x_cvpathname = gensym(buf); + outlet_new((t_object *)x, &s_anything); + /* LATER consider estimating these, based on widget class and options */ + x->x_width = 50; + x->x_height = 50; + props_clone(x->x_arguments, widgettype_getarguments(x->x_typedef)); + widget_addmessage(x, 0, ac, av); + x->x_filehandle = hammerfile_new((t_pd *)x, 0, 0, 0, 0); + x->x_transclock = clock_new(x, (t_method)widget_transtick); + x->x_background = 0; + x->x_hasstate = 0; + x->x_update = WIDGET_NOUPDATE; + x->x_disabled = 0; + widget_attach(x); + return (x); +} + +static t_glist *tow_getglist(t_tow *x, int complain) +{ + t_glist *glist = + (x->x_cvremote ? + (t_glist *)pd_findbyclass(x->x_cvremote, canvas_class) : x->x_glist); + if (!glist && complain) + loud_error((t_pd *)x, "bad canvas name '%s'", x->x_cvname->s_name); + return (glist); +} + +static void tow_bang(t_tow *x) +{ + t_widgetentry *we; + for (we = x->x_widgetlist; we; we = we->we_next) + widget_bang(we->we_widget); +} + +static void tow_float(t_tow *x, t_float f) +{ + t_widgetentry *we; + for (we = x->x_widgetlist; we; we = we->we_next) + widget_float(we->we_widget, f); +} + +static void tow_symbol(t_tow *x, t_symbol *s) +{ + t_widgetentry *we; + for (we = x->x_widgetlist; we; we = we->we_next) + widget_symbol(we->we_widget, s); +} + +static void tow_anything(t_tow *x, t_symbol *s, int ac, t_atom *av) +{ + t_widgetentry *we; + for (we = x->x_widgetlist; we; we = we->we_next) + typedmess((t_pd *)we->we_widget, s, ac, av); +} + +static void tow__callback(t_tow *x, t_symbol *s, int ac, t_atom *av) +{ + if (ac == 1) + { + if (av->a_type == A_FLOAT) + outlet_float(((t_object *)x)->ob_outlet, av->a_w.w_float); + else if (av->a_type == A_SYMBOL) + outlet_symbol(((t_object *)x)->ob_outlet, av->a_w.w_symbol); + } + else if (ac) + { + if (av->a_type == A_FLOAT) + outlet_list(((t_object *)x)->ob_outlet, &s_list, ac, av); + else if (av->a_type == A_SYMBOL) + outlet_anything(((t_object *)x)->ob_outlet, + av->a_w.w_symbol, ac - 1, av + 1); + } + else outlet_bang(((t_object *)x)->ob_outlet); +} + +static void tow_widgetattach(t_tow *x, t_widget *w) +{ + t_towentry *te = getbytes(sizeof(*te)); + t_widgetentry *we = getbytes(sizeof(*we)); + te->te_tow = x; + te->te_next = w->x_towlist; + w->x_towlist = te; + we->we_widget = w; + we->we_next = x->x_widgetlist; + x->x_widgetlist = we; + pd_bind((t_pd *)x, w->x_cbtarget); +#ifdef TOW_DEBUG + post("%s widget '%s' attached", w->x_type->s_name, w->x_cbtarget->s_name); +#endif +} + +static void tow_widgetdetach(t_tow *x, t_widget *w) +{ + t_widgetentry *we1, *we2; + for (we1 = 0, we2 = x->x_widgetlist; we2; we2 = we2->we_next) + { + if (we2->we_widget == w) + { +#ifdef TOW_DEBUG + post("%s widget '%s' detached by widget's destructor", + w->x_type->s_name, w->x_cbtarget->s_name); +#endif + pd_unbind((t_pd *)x, w->x_cbtarget); + if (we1) + we1->we_next = we2->we_next; + else + x->x_widgetlist = we2->we_next; + freebytes(we2, sizeof(*we2)); + return; + } + we1 = we2; + } + bug("tow_widgetdetach"); +} + +static void widget_attach(t_widget *x) +{ + t_tow *t; + for (t = towlist; t; t = t->x_next) + if (x->x_glist == tow_getglist(t, 0) && + t->x_type == x->x_type && t->x_name == x->x_name) + tow_widgetattach(t, x); +} + +static void widget_detach(t_widget *x) +{ + t_towentry *te; + while (te = x->x_towlist) + { + x->x_towlist = te->te_next; + tow_widgetdetach(te->te_tow, x); + freebytes(te, sizeof(*te)); + } +} + +static void tow_attach(t_tow *x) +{ + t_glist *glist = tow_getglist(x, 0); + if (glist) + { + t_gobj *g; + for (g = glist->gl_list; g; g = g->g_next) + { + if (*(t_pd *)g == widget_class) + { + t_widget *w = (t_widget *)g; + if (w->x_type == x->x_type && w->x_name == x->x_name) + tow_widgetattach(x, w); + } + } +#ifdef TOW_DEBUG + if (!x->x_widgetlist) + post("%s widget '%s' not found", + x->x_type->s_name, x->x_name->s_name); +#endif + } +#ifdef TOW_DEBUG + else post("glist '%s' not found", x->x_cvname->s_name); +#endif +} + +static void tow_detach(t_tow *x) +{ + t_widgetentry *we; + while (we = x->x_widgetlist) + { + t_widget *w = we->we_widget; + t_towentry *te1, *te2; + x->x_widgetlist = we->we_next; + pd_unbind((t_pd *)x, w->x_cbtarget); + freebytes(we, sizeof(*we)); + for (te1 = 0, te2 = w->x_towlist; te2; te2 = te2->te_next) + { + if (te2->te_tow == x) + { +#ifdef TOW_DEBUG + post("%s widget '%s' detached by tow's destructor", + w->x_type->s_name, w->x_cbtarget->s_name); +#endif + if (te1) + te1->te_next = te2->te_next; + else + w->x_towlist = te2->te_next; + freebytes(te2, sizeof(*te2)); + break; + } + te1 = te2; + } + if (!te2) bug("tow_detach"); + } +} + +#ifdef TOW_DEBUG +static void tow_debug(t_tow *x) +{ + t_widgetentry *we; + post("attached widgets:"); + for (we = x->x_widgetlist; we; we = we->we_next) + { + t_widget *w = we->we_widget; + t_towentry *te; + int other = 0, found = 0; + startpost("\t%s %s", w->x_type->s_name, w->x_cbtarget->s_name); + for (te = w->x_towlist; te; te = te->te_next) + if (te->te_tow == x) + found++; + else + other++; + post(" (%d other tow%s)", other, (other == 1 ? "" : "s")); + if (found != 1) post("BUG: listed %d times in widget's towlist", found); + } +} +#endif + +static void tow_free(t_tow *x) +{ + t_tow *t1, *t2; +#ifdef TOW_DEBUG + startpost("updating towlist..."); +#endif + for (t1 = 0, t2 = towlist; t2; t2 = t2->x_next) + { + if (t2 == x) + { + if (t1) + t1->x_next = t2->x_next; + else + towlist = t2->x_next; +#ifdef TOW_DEBUG + post("ok"); +#endif + break; + } + t1 = t2; + } + tow_detach(x); +} + +static void *tow_new(t_symbol *s1, t_symbol *s2, t_symbol *s3) +{ + t_tow *x = (t_tow *)pd_new(tow_class); + char buf[64]; + x->x_glist = canvas_getcurrent(); + if (s1 && s1 != &s_ && strcmp(s1->s_name, ".")) + x->x_cvremote = canvas_makebindsym(x->x_cvname = s1); + else + { + x->x_cvremote = 0; + x->x_cvname = x->x_glist->gl_name; + } + x->x_type = s2; + x->x_name = s3; + outlet_new((t_object *)x, &s_anything); + x->x_widgetlist = 0; + x->x_next = towlist; + towlist = x; + tow_attach(x); + return (x); +} + +void widget_setup(void) +{ + post("beware! this is widget %s, %s %s build...", + TOXY_VERSION, loud_ordinal(TOXY_BUILD), TOXY_RELEASE); + widgettype_setup(); + widget_class = class_new(gensym("widget"), + (t_newmethod)widget_new, + (t_method)widget_free, + sizeof(t_widget), 0, A_GIMME, 0); + class_setwidget(widget_class, &widget_behavior); + forky_setsavefn(widget_class, widget_save); + forky_setpropertiesfn(widget_class, widget_properties); + class_addbang(widget_class, widget_bang); + 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_remove, + gensym("remove"), A_SYMBOL, 0); + class_addmethod(widget_class, (t_method)widget_ini, + gensym("ini"), A_GIMME, 0); + class_addmethod(widget_class, (t_method)widget_tot, + gensym("tot"), A_GIMME, 0); + class_addmethod(widget_class, (t_method)widget_refresh, + gensym("refresh"), 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__callback, + gensym("_cb"), A_GIMME, 0); + class_addmethod(widget_class, (t_method)widget__inout, + gensym("_inout"), A_FLOAT, 0); + class_addmethod(widget_class, (t_method)widget__click, + gensym("_click"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); + class_addmethod(widget_class, (t_method)widget__motion, + gensym("_motion"), A_FLOAT, A_FLOAT, 0); +#ifdef WIDGET_DEBUG + class_addmethod(widget_class, (t_method)widget_debug, + gensym("debug"), 0); +#endif + hammerfile_setup(widget_class, 0); + + makeshift_class = class_new(gensym("text"), 0, 0, + sizeof(t_text), + CLASS_NOINLET | CLASS_PATCHABLE, 0); + + tow_class = class_new(gensym("tow"), + (t_newmethod)tow_new, + (t_method)tow_free, + sizeof(t_tow), 0, A_SYMBOL, A_SYMBOL, A_SYMBOL, 0); + class_addbang(tow_class, tow_bang); + class_addfloat(tow_class, tow_float); + class_addsymbol(tow_class, tow_symbol); + class_addanything(tow_class, tow_anything); + class_addmethod(tow_class, (t_method)tow__callback, + gensym("_cb"), A_GIMME, 0); +#ifdef TOW_DEBUG + class_addmethod(tow_class, (t_method)tow_debug, + gensym("debug"), 0); +#endif +} diff --git a/toxy/widgettype.c b/toxy/widgettype.c new file mode 100644 index 0000000..6f26c27 --- /dev/null +++ b/toxy/widgettype.c @@ -0,0 +1,300 @@ +/* Copyright (c) 2003 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#include <stdio.h> +#include <string.h> +#include "m_pd.h" +#include "common/loud.h" +#include "common/dict.h" +#include "common/props.h" +#include "toxy/scriptlet.h" +#include "widgettype.h" + +#define WIDGETTYPE_VERBOSE +//#define WIDGETTYPE_DEBUG + +struct _widgettype +{ + t_pd wt_pd; + t_symbol *wt_typekey; /* this is a typemap symbol */ + t_symbol *wt_tkclass; /* also 'undefined' flag (gensym symbol) */ + t_symbol *wt_tkpackage; /* gensym symbol */ + t_props *wt_options; + t_props *wt_handlers; + t_props *wt_arguments; + t_scriptlet *wt_iniscript; +}; + +struct _masterwidget +{ + t_pd mw_pd; + t_symbol *mw_target; + t_scriptlet *mw_setupscript; + t_dict *mw_typemap; + t_widgettype *mw_defaulttype; /* contains master iniscript */ + t_widgettype *mw_parsedtype; /* the type currently parsed, if loading */ + t_binbuf *mw_bb; /* auxiliary, LATER remove */ +}; + +static t_class *widgettype_class; +static t_class *masterwidget_class; + +static t_masterwidget *masterwidget = 0; + +static t_canvas *widgettype_cvhook(t_pd *z) +{ + return (0); +} + +static void widgettype_map(t_widgettype *wt, char *cls, char *pkg) +{ + wt->wt_tkclass = (cls ? gensym(cls) : 0); + wt->wt_tkpackage = (pkg ? gensym(pkg) : 0); +} + +static t_widgettype *widgettype_new(t_masterwidget *mw, + char *typ, char *cls, char *pkg) +{ + t_widgettype *wt = (t_widgettype *)pd_new(widgettype_class); + wt->wt_typekey = dict_key(mw->mw_typemap, typ); + widgettype_map(wt, cls, pkg); + wt->wt_options = props_new(0, "option", "-", 0, 0); + wt->wt_handlers = props_new(0, "handler", "@", wt->wt_options, 0); + wt->wt_arguments = props_new(0, "argument", "#", wt->wt_options, 0); + wt->wt_iniscript = scriptlet_new((t_pd *)wt, mw->mw_target, mw->mw_target, + 0, widgettype_cvhook); + dict_bind(mw->mw_typemap, (t_pd *)wt, wt->wt_typekey); + return (wt); +} + +static t_canvas *masterwidget_cvhook(t_pd *z) +{ + return (0); +} + +static t_scriptlet *masterwidget_cmnthook(t_pd *z, char *rc, + char sel, char *buf) +{ + t_masterwidget *mw = masterwidget; + if (!*buf) + return (0); + if (sel == '>') + { + t_symbol *typekey; + t_widgettype *typeval; + char *cls = scriptlet_nextword(buf); + char *pkg = (cls ? scriptlet_nextword(cls) : 0); + mw->mw_parsedtype = 0; + if (!cls) + cls = buf; + typekey = dict_key(mw->mw_typemap, buf); + typeval = (t_widgettype *)dict_value(mw->mw_typemap, typekey); + if (z == (t_pd *)mw) + { /* default.wid */ + if (typeval) + { + /* LATER rethink */ + loud_warning((t_pd *)mw, "redefinition of '%s'\ + in \"%s.wid\" file, ignored", buf, rc); + return (0); + } + } + else + { /* <type>.wid */ + if (z != (t_pd *)typeval) + { + loud_warning((t_pd *)mw, "alien definition of '%s'\ + in \"%s.wid\" file, ignored", buf, rc); + return (0); + } + } + if (pkg) + /* carve out a single word as pkg, LATER rethink */ + scriptlet_nextword(pkg); + if (typeval) + widgettype_map(typeval, cls, pkg); + else + typeval = widgettype_new(mw, buf, cls, pkg); + mw->mw_parsedtype = typeval; +#ifdef WIDGETTYPE_DEBUG + post("adding widget type '%s'", typeval->wt_typekey->s_name); +#endif + return (typeval->wt_iniscript); + } + else if (sel == '.') + { + if (mw->mw_parsedtype + && (*buf == '-' || *buf == '@' || *buf == '#')) + { + t_symbol *empty; + int ac; + /* LATER get rid of the binbuf thing */ + binbuf_text(mw->mw_bb, buf, strlen(buf)); + if (ac = binbuf_getnatom(mw->mw_bb)) + { + t_atom *av = binbuf_getvec(mw->mw_bb); + t_props *pp; + if (!(empty = props_add(pp = mw->mw_parsedtype->wt_options, + 0, ac, av)) && + !(empty = props_add(pp = mw->mw_parsedtype->wt_handlers, + 0, ac, av))) + empty = props_add(pp = mw->mw_parsedtype->wt_arguments, + 0, ac, av); + if (empty) + loud_warning((t_pd *)mw, + "no value given for %s '%s'\ + of a widget type '%s' in \"%s.wid\" file", + props_getname(pp), empty->s_name, + mw->mw_parsedtype->wt_typekey->s_name, rc); + } + } + } + return (0); +} + +t_widgettype *widgettype_get(t_symbol *s) +{ + t_widgettype *wt; + /* default.wid defs are NOT overridden by <type>.wid -- + feature stability comes first, LATER rethink */ + if (wt = (t_widgettype *)dict_value(masterwidget->mw_typemap, + dict_key(masterwidget->mw_typemap, + s->s_name))) + masterwidget->mw_parsedtype = 0; + else + { + /* first instance of a type not defined in default.wid */ + wt = widgettype_new(masterwidget, s->s_name, 0, 0); + masterwidget->mw_parsedtype = wt; + } + if (masterwidget->mw_parsedtype) + { + if (scriptlet_rcload(wt->wt_iniscript, s->s_name, ".wid", + masterwidget_cmnthook) == SCRIPTLET_OK) + { +#ifdef WIDGETTYPE_VERBOSE + post("using %s's initializer", s->s_name); +#endif + } + } + return (wt); +} + +int widgettype_isdefined(t_widgettype *wt) +{ + return (wt->wt_tkclass != 0); +} + +t_symbol *widgettype_tkclass(t_widgettype *wt) +{ + return (wt->wt_tkclass); +} + +t_props *widgettype_getoptions(t_widgettype *wt) +{ + return (wt->wt_options); +} + +t_props *widgettype_gethandlers(t_widgettype *wt) +{ + return (wt->wt_handlers); +} + +t_props *widgettype_getarguments(t_widgettype *wt) +{ + return (wt->wt_arguments); +} + +char *widgettype_getcontents(t_widgettype *wt, int *szp) +{ + return (scriptlet_getcontents(wt->wt_iniscript, szp)); +} + +int widgettype_evaluate(t_widgettype *wt, t_scriptlet *outsp, + int visedonly, int ac, t_atom *av, t_props *argprops) +{ + return (scriptlet_evaluate(wt->wt_iniscript, outsp, + visedonly, ac, av, argprops)); +} + +int masterwidget_evaluate(t_scriptlet *outsp, int visedonly, + int ac, t_atom *av, t_props *argprops) +{ + return (scriptlet_evaluate(masterwidget->mw_defaulttype->wt_iniscript, + outsp, visedonly, ac, av, argprops)); +} + +void widgettype_setup(void) +{ + static int done = 0; + if (!done) + { + widgettype_class = class_new(gensym("widget type"), 0, 0, + sizeof(t_widgettype), CLASS_PD, 0); + masterwidget_class = class_new(gensym("Widget"), 0, 0, + sizeof(t_masterwidget), CLASS_PD, 0); + done = 1; + } +} + +void masterwidget_initialize(void) +{ + t_scriptlet *sp; + t_symbol *typekey; + t_widgettype *typeval; + char buf[MAXPDSTRING]; + if (masterwidget) + return; + masterwidget = (t_masterwidget *)pd_new(masterwidget_class); + sprintf(buf, "mw%x", (int)masterwidget); + /* never unbound, LATER rethink */ + pd_bind((t_pd *)masterwidget, masterwidget->mw_target = gensym(buf)); + + masterwidget->mw_typemap = dict_new(0); + + sp = masterwidget->mw_setupscript = + scriptlet_new((t_pd *)masterwidget, masterwidget->mw_target, + masterwidget->mw_target, 0, 0); + masterwidget->mw_parsedtype = 0; + masterwidget->mw_bb = binbuf_new(); + + if (scriptlet_rcload(sp, "default", ".wid", + masterwidget_cmnthook) == SCRIPTLET_OK) + { +#ifdef WIDGETTYPE_VERBOSE + post("using file 'default.wid'"); +#endif + } + else + { + loud_warning((t_pd *)masterwidget, "missing file 'default.wid'"); + + /* no setup scriptlet, LATER use built-in default */ +#if 0 + scriptlet_reset(sp); + scriptlet_addstring(sp, ... +#endif + } + typekey = dict_key(masterwidget->mw_typemap, "default"); + if (typeval = (t_widgettype *)dict_value(masterwidget->mw_typemap, typekey)) + masterwidget->mw_defaulttype = typeval; + else + { + /* no master initializer, LATER use built-in default */ + masterwidget->mw_defaulttype = + widgettype_new(masterwidget, "default", 0, 0); + sp = masterwidget->mw_defaulttype->wt_iniscript; +#if 0 + scriptlet_reset(sp); + scriptlet_addstring(sp, ... +#endif + } + sp = scriptlet_new((t_pd *)masterwidget, + masterwidget->mw_target, masterwidget->mw_target, 0, 0); + if (scriptlet_evaluate(masterwidget->mw_setupscript, sp, 0, 0, 0, 0)) + scriptlet_push(sp); + else + bug("masterwidget_initialize"); + scriptlet_free(sp); +} diff --git a/toxy/widgettype.h b/toxy/widgettype.h new file mode 100644 index 0000000..55c8e9d --- /dev/null +++ b/toxy/widgettype.h @@ -0,0 +1,30 @@ +/* Copyright (c) 2003 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#ifndef __WIDGETTYPE_H__ +#define __WIDGETTYPE_H__ + +EXTERN_STRUCT _widgettype; +#define t_widgettype struct _widgettype + +EXTERN_STRUCT _masterwidget; +#define t_masterwidget struct _masterwidget + +t_widgettype *widgettype_get(t_symbol *s); +int widgettype_isdefined(t_widgettype *wt); +t_symbol *widgettype_tkclass(t_widgettype *wt); +t_props *widgettype_getoptions(t_widgettype *wt); +t_props *widgettype_gethandlers(t_widgettype *wt); +t_props *widgettype_getarguments(t_widgettype *wt); +char *widgettype_propname(t_symbol *s); +char *widgettype_getcontents(t_widgettype *wt, int *szp); +int widgettype_evaluate(t_widgettype *wt, t_scriptlet *outsp, + int visedonly, int ac, t_atom *av, t_props *argprops); +int masterwidget_evaluate(t_scriptlet *outsp, int visedonly, + int ac, t_atom *av, t_props *argprops); +void masterwidget_initialize(void); + +void widgettype_setup(void); + +#endif |