From 63df5d827bc4ffa7131222f96b0f68db1674d18a Mon Sep 17 00:00:00 2001 From: Ivica Ico Bukvic <ico@vt.edu> Date: Fri, 21 Mar 2014 21:13:46 -0400 Subject: [PATCH] *Jonathan Wilkes' 2 patches addressing: - nested plots display properly - plot is vis'd and unvis'd properly when deleting plot or struct - commented out ugly plot_displace hack-- multiple plots should work just fine - separated out garray dependencies into class "old_plot". This way the changes I made don't affect garrays. _Very_ ugly hack, but it was pretty simple to implement and will be easy to remove later. - no crashes when non-existent arrays are entered into a [struct] that has scalars hanging around - template_cancreate ported from 0.45 - added a function to get the offending struct (to use with "Find last error"). Not using it yet, though. + For creating scalars using an object box: - scalar must have initial "float x float y" fields, in that order. This means you can't accidentally type the name of the hidden garray structs and create a scalar. (Nor any other structs that only have a "y" field, etc.) - broken object box returned if the struct has a bogus array template. (Although currently I'm just refusing to create such a struct.) --- pd/src/g_array.c | 2 +- pd/src/g_canvas.c | 5 +- pd/src/g_canvas.h | 3 + pd/src/g_scalar.c | 106 +++++- pd/src/g_template.c | 873 ++++++++++++++++++++++++++++++++++++++++++-- pd/src/g_text.c | 5 +- pd/src/m_pd.h | 2 +- 7 files changed, 970 insertions(+), 26 deletions(-) diff --git a/pd/src/g_array.c b/pd/src/g_array.c index 23f4c89fe..a05fffab4 100644 --- a/pd/src/g_array.c +++ b/pd/src/g_array.c @@ -151,7 +151,7 @@ static char garray_arraytemplatefile[] = "\ #N canvas 0 0 458 153 10;\n\ #X obj 43 31 struct _float_array array z float float style\n\ float linewidth float color symbol fillcolor symbol outlinecolor;\n\ -#X obj 43 70 plot z color linewidth 0 0 1 style fillcolor outlinecolor;\n\ +#X obj 43 70 old_plot z color linewidth 0 0 1 style fillcolor outlinecolor;\n\ "; static char garray_floattemplatefile[] = "\ #N canvas 0 0 458 153 10;\n\ diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c index 443190026..a6d5f8c71 100644 --- a/pd/src/g_canvas.c +++ b/pd/src/g_canvas.c @@ -1634,7 +1634,10 @@ static void glist_redrawall(t_template *template, t_glist *gl, int action) { t_class *cl; if (vis && g->g_pd == scalar_class && - template == template_findbyname(((t_scalar *)g)->sc_template)) + ((template == template_findbyname(((t_scalar *)g)->sc_template)) + || template_has_elemtemplate( + template_findbyname(((t_scalar *)g)->sc_template), + template))) { if (action == 1) { diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h index 060ce24a1..50a7ec8db 100644 --- a/pd/src/g_canvas.h +++ b/pd/src/g_canvas.h @@ -629,6 +629,7 @@ EXTERN t_scalar *scalar_new(t_glist *owner, EXTERN void word_free(t_word *wp, t_template *tmpl); EXTERN void scalar_getbasexy(t_scalar *x, t_float *basex, t_float *basey); EXTERN void scalar_redraw(t_scalar *x, t_glist *glist); +EXTERN int template_has_elemtemplate(t_template *t, t_template *template); /* ------helper routines for "garrays" and "plots" -------------- */ EXTERN int array_doclick(t_array *array, t_glist *glist, t_scalar *sc, t_array *ap, @@ -666,6 +667,8 @@ EXTERN void template_setsymbol(t_template *x, t_symbol *fieldname, EXTERN t_template *gtemplate_get(t_gtemplate *x); EXTERN t_template *template_findbyname(t_symbol *s); +EXTERN int template_cancreate(t_template *template); +EXTERN int template_hasxy(t_template *template); EXTERN t_canvas *template_findcanvas(t_template *tmpl); EXTERN void template_notify(t_template *tmpl, t_symbol *s, int argc, t_atom *argv); diff --git a/pd/src/g_scalar.c b/pd/src/g_scalar.c index fca3ec39a..430f847c7 100644 --- a/pd/src/g_scalar.c +++ b/pd/src/g_scalar.c @@ -87,6 +87,74 @@ void word_free(t_word *wp, t_template *template) } } +/* some of this code is used in a function in g_canvas.c... + need to modularize it */ +static t_object *template_getstruct(t_template *template) +{ + if (template) + { + t_gobj *y; + t_canvas *c; + if (c = template_findcanvas(template)) + { + t_symbol *s1 = gensym("struct"); + for (y = c->gl_list; y; y = y->g_next) + { + t_object *ob = pd_checkobject(&y->g_pd); + t_atom *argv; + if (!ob || ob->te_type != T_OBJECT || + binbuf_getnatom(ob->te_binbuf) < 2) + continue; + argv = binbuf_getvec(ob->te_binbuf); + if (argv[0].a_w.w_symbol != s1) + continue; + if (canvas_makebindsym(argv[1].a_w.w_symbol) == template->t_sym) + return (ob); + } + } + } + return (0); +} + +int template_hasxy(t_template *template) +{ + t_symbol *zz; + int xonset, yonset, xtype, ytype, gotx, goty; + if (!template) + { + error("struct: couldn't find template %s", template->t_sym->s_name); + return 0; + } + gotx = template_find_field(template, gensym("x"), &xonset, &xtype, &zz); + goty = template_find_field(template, gensym("y"), &yonset, &ytype, &zz); + if ((gotx && (xtype == DT_FLOAT)) && + (goty && (ytype == DT_FLOAT)) && + (xonset == 0) && (yonset == sizeof(t_word))) + { + return 1; + } + else + return 0; +} + +int template_cancreate(t_template *template) +{ + int i, type, nitems = template->t_n; + t_dataslot *datatypes = template->t_vec; + t_template *elemtemplate; + for (i = 0; i < nitems; i++, datatypes++) + if (datatypes->ds_type == DT_ARRAY && + (!(elemtemplate = template_findbyname(datatypes->ds_arraytemplate)) + || !template_cancreate(elemtemplate))) + { + t_object *ob = template_getstruct(template); + pd_error(ob, "%s: no such template", + datatypes->ds_arraytemplate->s_name); + return (0); + } + return (1); +} + /* make a new scalar and add to the glist. We create a "gp" here which will be used for array items to point back here. This gp doesn't do reference counting or "validation" updates though; the parent won't go away @@ -105,6 +173,8 @@ t_scalar *scalar_new(t_glist *owner, t_symbol *templatesym) error("scalar: couldn't find template %s", templatesym->s_name); return (0); } + if (!template_cancreate(template)) + return (0); x = (t_scalar *)getbytes(sizeof(t_scalar) + (template->t_n - 1) * sizeof(*x->sc_vec)); x->sc_gobj.g_pd = scalar_class; @@ -147,6 +217,36 @@ void glist_scalar(t_glist *glist, binbuf_free(b); } + /* search template fields recursively to see if the template + depends on elemtemplate */ +int template_has_elemtemplate(t_template *t, t_template *elemtemplate) +{ + int returnval = 0; + if (t && elemtemplate) + { + int i; + t_dataslot *d = t->t_vec; + for (i = 0; i < t->t_n; i++, d++) + { + if (d->ds_type == DT_ARRAY) + { + if (d->ds_arraytemplate == elemtemplate->t_sym) + { + returnval = 1; + break; + } + else + { + returnval = template_has_elemtemplate( + template_findbyname(d->ds_arraytemplate), + elemtemplate); + } + } + } + } + return (returnval); +} + /* -------------------- widget behavior for scalar ------------ */ void scalar_getbasexy(t_scalar *x, t_float *basex, t_float *basey) { @@ -506,8 +606,11 @@ static void scalar_displace_withtag(t_gobj *z, t_glist *glist, int dx, int dy) behavior, so we don't use the hack for them. (Non-garray scalars should follow that behavior too, but cannot atm for the reason given in the comment above scalar_select...) - */ + Apparently this is no longer needed, so it is commented out. Once + we test it we should be able to delete it for good... */ + + /* if (template->t_sym != gensym("_float_array")) { t_gobj *y; @@ -520,6 +623,7 @@ static void scalar_displace_withtag(t_gobj *z, t_glist *glist, int dx, int dy) basex, basey, dx, dy); } } + */ //scalar_redraw(x, glist); } diff --git a/pd/src/g_template.c b/pd/src/g_template.c index 37f3f83f5..349ac4315 100644 --- a/pd/src/g_template.c +++ b/pd/src/g_template.c @@ -588,6 +588,7 @@ static void *gtemplate_donew(t_symbol *sym, int argc, t_atom *argv) } t_gtemplate *x = (t_gtemplate *)pd_new(gtemplate_class); t_template *t = template_findbyname(sym); + int i; t_symbol *sx = gensym("x"); x->x_owner = canvas_getcurrent(); @@ -618,6 +619,17 @@ static void *gtemplate_donew(t_symbol *sym, int argc, t_atom *argv) /* if there's none, we just replace the template with our own and conform it. */ t_template *y = template_new(&s_, argc, argv); + + /* I'm not _exactly_ sure about this. It's possible + that the user could screw up a nested array construction + and end up with scalars that aren't able to conform. On + the other hand, this keeps us from crashing if a non- + existent array template is typed into the box. */ + if (!template_cancreate(y)) + { + return 0; + } + canvas_redrawallfortemplate(t, 2); /* Unless the new template is different from the old one, there's nothing to do. */ @@ -4032,8 +4044,13 @@ static void plot_displace(t_gobj *z, t_glist *glist, int dx, int dy) { /* a very temporary hack. See comment inside scalar_displace_withtag */ + + /* Looks like it's no longer needed, so we're commenting it out for + the time being. */ + /* sys_vgui(".x%lx.c move .x%lx.x%lx.template%lx %d %d\n", glist_getcanvas(glist), glist_getcanvas(glist), glist, data, dx, dy); + */ /* not yet */ } @@ -4110,6 +4127,11 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc, if (tovis) { + int in_array = (sc->sc_vec == data) ? 0 : 1; + if (in_array) + sys_vgui(".x%lx.c create group -tags {.scelem%lx} " + "-parent .dgroup%lx -matrix { {1 0} {0 1} {%g %g} }\n", + glist_getcanvas(glist), data, sc->sc_vec, basex, basey); /* check if old 3-digit color field is being used... */ int dscolor = fielddesc_getfloat(&x->x_outlinecolor, template, data, 1); if (dscolor != 0) @@ -4126,15 +4148,16 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc, t_float minyval = 1e20, maxyval = -1e20; int ndrawn = 0; sys_vgui(".x%lx.c create path { \\\n", glist_getcanvas(glist)); - for (xsum = basex + xloc, i = 0; i < nelem; i++) + for (xsum = xloc, i = 0; i < nelem; i++) { t_float yval, xpix, ypix, nextxloc; int ixpix, inextx; if (xonset >= 0) { - usexloc = basex + xloc + + usexloc = xloc + *(t_float *)((elem + elemsize * i) + xonset); +// revisite xtopixels... ixpix = glist_xtopixels(glist, fielddesc_cvttocoord(xfielddesc, usexloc)); inextx = ixpix + 2; @@ -4162,7 +4185,7 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc, int border = 0; if(style == PLOTSTYLE_POINTS) py2 = (int)(glist_ytopixels(glist, - basey + fielddesc_cvttocoord(yfielddesc, maxyval)) + fielddesc_cvttocoord(yfielddesc, maxyval)) + linewidth) - 1; else { @@ -4204,19 +4227,21 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc, a separate canvas item for each element... sys_vgui(".x%lx.c create prect %d %d %d %d -fill %s " "-stroke %s -strokewidth %d " + "-parent .dgroup%lx " "-tags {.x%lx.x%lx.template%lx array}\n", glist_getcanvas(glist), ixpix, (int)glist_ytopixels(glist, - basey + fielddesc_cvttocoord(yfielddesc, minyval)) - 1, + fielddesc_cvttocoord(yfielddesc, minyval)) - 1, inextx, py2, symfill->s_name, symoutline->s_name, - border, glist_getcanvas(glist), glist, data); + border, data, + glist_getcanvas(glist), glist, data); */ /* For efficiency, we make a single path item for the trace or bargraph */ int mex1 = ixpix; int mey1 = (int)glist_ytopixels(glist, - basey + fielddesc_cvttocoord(yfielddesc, minyval)) - 1; + fielddesc_cvttocoord(yfielddesc, minyval)) - 1; int mex2 = inextx; int mey2 = py2; sys_vgui("M %d %d H %d V %d H %d z \\\n", @@ -4230,10 +4255,17 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc, } /* end of the path item from above */ sys_vgui("} -fill %s -stroke %s -strokewidth %d " - "-tags {.x%lx.x%lx.template%lx array}\n", + "-parent {.dgroup%lx} " + "-tags {.x%lx.x%lx.template%lx array}\\\n", symfill->s_name, symoutline->s_name, style == PLOTSTYLE_POINTS ? 0 : 1, + data, glist_getcanvas(glist), glist, data); + if (in_array) + sys_vgui("-parent .scelem%lx \n", data); + else + sys_vgui("-parent .dgroup%lx \n", sc->sc_vec); + } else { @@ -4262,13 +4294,13 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc, else yval = 0; wval = *(t_float *)((elem + elemsize * i) + wonset); xpix = glist_xtopixels(glist, - basex + fielddesc_cvttocoord(xfielddesc, usexloc)); + fielddesc_cvttocoord(xfielddesc, usexloc)); ixpix = xpix + 0.5; if (xonset >= 0 || ixpix != lastpixel) { sys_vgui("%d %f \\\n", ixpix, glist_ytopixels(glist, - basey + fielddesc_cvttocoord(yfielddesc, + fielddesc_cvttocoord(yfielddesc, yloc + yval) - fielddesc_cvttocoord(wfielddesc,wval))); ndrawn++; @@ -4289,12 +4321,12 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc, else yval = 0; wval = *(t_float *)((elem + elemsize * i) + wonset); xpix = glist_xtopixels(glist, - basex + fielddesc_cvttocoord(xfielddesc, usexloc)); + fielddesc_cvttocoord(xfielddesc, usexloc)); ixpix = xpix + 0.5; if (xonset >= 0 || ixpix != lastpixel) { sys_vgui("%d %f \\\n", ixpix, glist_ytopixels(glist, - basey + yloc + fielddesc_cvttocoord(yfielddesc, + yloc + fielddesc_cvttocoord(yfielddesc, yval) + fielddesc_cvttocoord(wfielddesc, wval))); ndrawn++; @@ -4307,11 +4339,11 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc, if (ndrawn < 4) { sys_vgui("%d %f \\\n", ixpix + 10, glist_ytopixels(glist, - basey + yloc + fielddesc_cvttocoord(yfielddesc, + yloc + fielddesc_cvttocoord(yfielddesc, yval) + fielddesc_cvttocoord(wfielddesc, wval))); sys_vgui("%d %f \\\n", ixpix + 10, glist_ytopixels(glist, - basey + yloc + fielddesc_cvttocoord(yfielddesc, + yloc + fielddesc_cvttocoord(yfielddesc, yval) - fielddesc_cvttocoord(wfielddesc, wval))); } @@ -4320,7 +4352,10 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc, symfill->s_name, symoutline->s_name); // this doesn't work with tkpath... //if (style == PLOTSTYLE_BEZ) sys_vgui("-smooth 1 \\\n"); - + if (in_array) + sys_vgui(" -parent .scelem%lx \\\n", data); + else + sys_vgui(" -parent .dgroup%lx \\\n", sc->sc_vec); sys_vgui("-tags {.x%lx.x%lx.template%lx scalar%lx}\n", glist_getcanvas(glist), glist, data, sc); } @@ -4342,13 +4377,13 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc, yval = *(t_float *)((elem + elemsize * i) + yonset); else yval = 0; xpix = glist_xtopixels(glist, - basex + fielddesc_cvttocoord(xfielddesc, usexloc)); + fielddesc_cvttocoord(xfielddesc, usexloc)); ixpix = xpix + 0.5; if (xonset >= 0 || ixpix != lastpixel) { sys_vgui("%d %f \\\n", ixpix, glist_ytopixels(glist, - basey + yloc + fielddesc_cvttocoord(yfielddesc, + yloc + fielddesc_cvttocoord(yfielddesc, yval))); ndrawn++; } @@ -4358,7 +4393,7 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc, /* TK will complain if there aren't at least 2 points... */ if (ndrawn == 0) sys_vgui("0 0 0 0 \\\n"); else if (ndrawn == 1) sys_vgui("%d %f \\\n", ixpix + 10, - glist_ytopixels(glist, basey + yloc + + glist_ytopixels(glist, yloc + fielddesc_cvttocoord(yfielddesc, yval))); //sys_vgui("-strokewidth %f \\\n", linewidth); @@ -4366,8 +4401,13 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc, sys_vgui("-strokewidth %f -stroke %s \\\n", linewidth, symoutline->s_name); //sys_vgui("-fill %s \\\n", symoutline->s_name); //if (style == PLOTSTYLE_BEZ) sys_vgui("-smooth 1 \\\n"); //this doesn't work with tkpath + if (in_array) + sys_vgui(" -parent .scelem%lx \\\n", data); + else + sys_vgui(" -parent .dgroup%lx \\\n", sc->sc_vec); - sys_vgui("-tags {.x%lx.x%lx.template%lx scalar%lx}\n", glist_getcanvas(glist), glist, data,sc); + sys_vgui("-tags {.x%lx.x%lx.template%lx scalar%lx}\n", + glist_getcanvas(glist), glist, data,sc); } } /* make sure the array drawings are behind the graph */ @@ -4379,18 +4419,20 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc, searched for drawing instructions for every last point. */ if (scalarvis != 0) { + t_float xoffset = in_array ? basex : 0; + t_float yoffset = in_array ? basey : 0; for (xsum = xloc, i = 0; i < nelem; i++) { t_float usexloc, useyloc; t_gobj *y; if (xonset >= 0) - usexloc = /* basex */ + xloc + + usexloc = xloc + xoffset + *(t_float *)((elem + elemsize * i) + xonset); - else usexloc = /* basex */ + xsum, xsum += xinc; + else usexloc = xoffset + xsum, xsum += xinc; if (yonset >= 0) yval = *(t_float *)((elem + elemsize * i) + yonset); else yval = 0; - useyloc = /* basey */ + yloc + + useyloc = yloc + yoffset + fielddesc_cvttocoord(yfielddesc, yval); for (y = elemtemplatecanvas->gl_list; y; y = y->g_next) { @@ -4425,6 +4467,7 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc, { /* un-draw the individual points */ //fprintf(stderr,"plot_vis UNVIS\n"); + if (scalarvis != 0) { int i; @@ -4441,6 +4484,7 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc, } } } + /* and then the trace */ sys_vgui(".x%lx.c delete .x%lx.x%lx.template%lx\n", glist_getcanvas(glist), glist_getcanvas(glist), glist, data); @@ -4517,6 +4561,790 @@ static void plot_setup(void) class_setparentwidget(plot_class, &plot_widgetbehavior); } +/* --------- old plot code used for garrays --------------- */ + +t_class *old_plot_class; + +typedef struct _old_plot +{ + t_object x_obj; + t_canvas *x_canvas; + t_fielddesc x_outlinecolor; + t_fielddesc x_width; + t_fielddesc x_xloc; + t_fielddesc x_yloc; + t_fielddesc x_xinc; + t_fielddesc x_style; + t_fielddesc x_data; + t_fielddesc x_xpoints; + t_fielddesc x_ypoints; + t_fielddesc x_wpoints; + t_fielddesc x_vis; /* visible */ + t_fielddesc x_scalarvis; /* true if drawing the scalar at each point */ + t_fielddesc x_symoutlinecolor; /* color as hex symbol */ + t_fielddesc x_symfillcolor; /* fill color as hex symbol */ +} t_old_plot; + +static void *old_plot_new(t_symbol *classsym, t_int argc, t_atom *argv) +{ + t_old_plot *x = (t_old_plot *)pd_new(old_plot_class); + int defstyle = PLOTSTYLE_POLY; + x->x_canvas = canvas_getcurrent(); + //fprintf(stderr,"plot new %s\n", + // (canvas_makebindsym(x->x_canvas->gl_name))->s_name); + t_template *t = template_findbyname( + canvas_makebindsym(x->x_canvas->gl_name)); + if (t) + { + /* increment variable of the template + to prevent transform as that would + make arrays break their hitboxes + and all kinds of other bad stuff */ + t->t_transformable++; + } + + fielddesc_setfloat_var(&x->x_xpoints, gensym("x")); + fielddesc_setfloat_var(&x->x_ypoints, gensym("y")); + fielddesc_setfloat_var(&x->x_wpoints, gensym("w")); + + fielddesc_setfloat_const(&x->x_vis, 1); + fielddesc_setfloat_const(&x->x_scalarvis, 1); + while (1) + { + t_symbol *firstarg = atom_getsymbolarg(0, argc, argv); + if (!strcmp(firstarg->s_name, "curve") || + !strcmp(firstarg->s_name, "-c")) + { + defstyle = PLOTSTYLE_BEZ; + argc--, argv++; + } + else if (!strcmp(firstarg->s_name, "-v") && argc > 1) + { + fielddesc_setfloatarg(&x->x_vis, 1, argv+1); + argc -= 2; argv += 2; + } + else if (!strcmp(firstarg->s_name, "-vs") && argc > 1) + { + fielddesc_setfloatarg(&x->x_scalarvis, 1, argv+1); + argc -= 2; argv += 2; + } + else if (!strcmp(firstarg->s_name, "-x") && argc > 1) + { + fielddesc_setfloatarg(&x->x_xpoints, 1, argv+1); + argc -= 2; argv += 2; + } + else if (!strcmp(firstarg->s_name, "-y") && argc > 1) + { + fielddesc_setfloatarg(&x->x_ypoints, 1, argv+1); + argc -= 2; argv += 2; + } + else if (!strcmp(firstarg->s_name, "-w") && argc > 1) + { + fielddesc_setfloatarg(&x->x_wpoints, 1, argv+1); + argc -= 2; argv += 2; + } + else break; + } + if (argc) fielddesc_setarrayarg(&x->x_data, argc--, argv++); + else fielddesc_setfloat_const(&x->x_data, 1); + if (argc) fielddesc_setfloatarg(&x->x_outlinecolor, argc--, argv++); + else fielddesc_setfloat_const(&x->x_outlinecolor, 0); + if (argc) fielddesc_setfloatarg(&x->x_width, argc--, argv++); + else fielddesc_setfloat_const(&x->x_width, 1); + if (argc) fielddesc_setfloatarg(&x->x_xloc, argc--, argv++); + else fielddesc_setfloat_const(&x->x_xloc, 1); + if (argc) fielddesc_setfloatarg(&x->x_yloc, argc--, argv++); + else fielddesc_setfloat_const(&x->x_yloc, 1); + if (argc) fielddesc_setfloatarg(&x->x_xinc, argc--, argv++); + else fielddesc_setfloat_const(&x->x_xinc, 1); + if (argc) fielddesc_setfloatarg(&x->x_style, argc--, argv++); + else fielddesc_setfloat_const(&x->x_style, defstyle); + if (argc) fielddesc_setsymbolarg(&x->x_symfillcolor, argc--, argv++); + else argc--, argv++; + if (argc) fielddesc_setsymbolarg(&x->x_symoutlinecolor, argc--, argv++); + + return (x); +} + +void old_plot_float(t_old_plot *x, t_floatarg f) +{ + int viswas; + if (x->x_vis.fd_type != A_FLOAT || x->x_vis.fd_var) + { + pd_error(x, "global vis/invis for a template with variable visibility"); + return; + } + viswas = (x->x_vis.fd_un.fd_float != 0); + + if ((f != 0 && viswas) || (f == 0 && !viswas)) + return; + canvas_redrawallfortemplatecanvas(x->x_canvas, 2); + fielddesc_setfloat_const(&x->x_vis, (f != 0)); + canvas_redrawallfortemplatecanvas(x->x_canvas, 1); +} + +/* -------------------- widget behavior for plot ------------ */ + + + /* get everything we'll need from the owner template of the array being + plotted. Not used for garrays, but see below */ +static int old_plot_readownertemplate(t_old_plot *x, + t_word *data, t_template *ownertemplate, + t_symbol **elemtemplatesymp, t_array **arrayp, + t_float *linewidthp, t_float *xlocp, t_float *xincp, t_float *ylocp, t_float *stylep, + t_float *visp, t_float *scalarvisp, + t_fielddesc **xfield, t_fielddesc **yfield, t_fielddesc **wfield, t_symbol **fillcolorp, + t_symbol **outlinecolorp) +{ + int arrayonset, type; + t_symbol *elemtemplatesym; + t_array *array; + + /* find the data and verify it's an array */ + if (x->x_data.fd_type != A_ARRAY || !x->x_data.fd_var) + { + error("old_plot: needs an array field"); + return (-1); + } + if (!template_find_field(ownertemplate, x->x_data.fd_un.fd_varsym, + &arrayonset, &type, &elemtemplatesym)) + { + error("old_plot: %s: no such field", x->x_data.fd_un.fd_varsym->s_name); + return (-1); + } + if (type != DT_ARRAY) + { + error("old_plot: %s: not an array", x->x_data.fd_un.fd_varsym->s_name); + return (-1); + } + array = *(t_array **)(((char *)data) + arrayonset); + *linewidthp = fielddesc_getfloat(&x->x_width, ownertemplate, data, 1); + *xlocp = fielddesc_getfloat(&x->x_xloc, ownertemplate, data, 1); + *xincp = fielddesc_getfloat(&x->x_xinc, ownertemplate, data, 1); + *ylocp = fielddesc_getfloat(&x->x_yloc, ownertemplate, data, 1); + *stylep = fielddesc_getfloat(&x->x_style, ownertemplate, data, 1); + *visp = fielddesc_getfloat(&x->x_vis, ownertemplate, data, 1); + *scalarvisp = fielddesc_getfloat(&x->x_scalarvis, ownertemplate, data, 1); + *elemtemplatesymp = elemtemplatesym; + *arrayp = array; + *xfield = &x->x_xpoints; + *yfield = &x->x_ypoints; + *wfield = &x->x_wpoints; + *fillcolorp = fielddesc_getsymbol(&x->x_symfillcolor, ownertemplate, + data, 0); + *outlinecolorp = fielddesc_getsymbol(&x->x_symoutlinecolor, ownertemplate, + data, 0); + + return (0); +} + +static void old_plot_getrect(t_gobj *z, t_glist *glist, + t_word *data, t_template *template, t_float basex, t_float basey, + int *xp1, int *yp1, int *xp2, int *yp2) +{ + //fprintf(stderr,"plot_getrect\n"); + t_old_plot *x = (t_old_plot *)z; + int elemsize, yonset, wonset, xonset; + t_canvas *elemtemplatecanvas; + t_template *elemtemplate; + t_symbol *elemtemplatesym; + t_symbol *symfillcolor; + t_symbol *symoutlinecolor; + t_float linewidth, xloc, xinc, yloc, style, xsum, yval, vis, scalarvis; + t_array *array; + int x1 = 0x7fffffff, y1 = 0x7fffffff, x2 = -0x7fffffff, y2 = -0x7fffffff; + int i; + t_float xpix1, xpix2, ypix, wpix; + t_fielddesc *xfielddesc, *yfielddesc, *wfielddesc; + /* if we're the only plot in the glist claim the whole thing */ + /*if (glist->gl_list && !glist->gl_list->g_next) + { + *xp1 = *yp1 = -0x7fffffff; + *xp2 = *yp2 = 0x7fffffff; + return; + }*/ + if (!old_plot_readownertemplate(x, data, template, + &elemtemplatesym, &array, &linewidth, &xloc, &xinc, &yloc, &style, + &vis, &scalarvis, &xfielddesc, &yfielddesc, &wfielddesc, + &symfillcolor, &symoutlinecolor) && + (vis != 0) && + !array_getfields(elemtemplatesym, &elemtemplatecanvas, + &elemtemplate, &elemsize, + xfielddesc, yfielddesc, wfielddesc, + &xonset, &yonset, &wonset)) + { + /* if it has more than 2000 points, just check 1000 of them. */ + int incr = (array->a_n <= 2000 ? 1 : array->a_n / 1000); + for (i = 0, xsum = 0; i < array->a_n; i += incr) + { + t_float usexloc, useyloc; + t_gobj *y; + /* get the coords of the point proper */ + array_getcoordinate(glist, (char *)(array->a_vec) + i * elemsize, + xonset, yonset, wonset, i, basex + xloc, basey + yloc, xinc, + xfielddesc, yfielddesc, wfielddesc, + &xpix1, &xpix2, &ypix, &wpix); + //fprintf(stderr,"elemsize%d yonset%d wonset%d xonset%d " + // "i%d basex%f xloc%f basey%f yloc%f xinc%f " + // "xpix%f ypix%f wpix%f\n", + // elemsize, yonset, wonset, xonset, i, basex, xloc, basey, yloc, + // xinc, xpix, ypix, wpix); + if (xpix1 < x1) + x1 = xpix1; + if (xpix2 > x2) + x2 = xpix2; + if (ypix - wpix < y1) + y1 = ypix - wpix; + if (ypix + wpix > y2) + y2 = ypix + wpix; + + //fprintf(stderr,"plot_getrect %d %d %d %d\n", x1, y1, x2, y2); + + if (scalarvis != 0) + { + /* check also the drawing instructions for the scalar */ + if (xonset >= 0) + usexloc = basex + xloc + fielddesc_cvttocoord(xfielddesc, + *(t_float *)(((char *)(array->a_vec) + elemsize * i) + + xonset)); + //else usexloc = x1; //usexloc = basex + xsum, xsum += xinc; + usexloc = basex + xsum, xsum += xinc; + if (yonset >= 0) + yval = *(t_float *)(((char *)(array->a_vec) + elemsize * i) + + yonset); + else yval = 0; + //useyloc = (y1+y2)/2; //basey + yloc + fielddesc_cvttocoord(yfielddesc, yval); + useyloc = basey + yloc + fielddesc_cvttocoord(yfielddesc, yval); + for (y = elemtemplatecanvas->gl_list; y; y = y->g_next) + { + //fprintf(stderr,".-.-. usexloc %f useyloc %f " + // "(alt %f %f)\n", + // usexloc, useyloc, + // basex + xloc + + // fielddesc_cvttocoord(xfielddesc, + // *(t_float *)(((char *)(array->a_vec) + elemsize * i) + // + xonset)), + // *(t_float *)(((char *)(array->a_vec) + elemsize * i) + + // yonset)); + int xx1, xx2, yy1, yy2; + t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd); + if (!wb) continue; + (*wb->w_parentgetrectfn)(y, glist, + (t_word *)((char *)(array->a_vec) + elemsize * i), + elemtemplate, usexloc, useyloc, + &xx1, &yy1, &xx2, &yy2); + //fprintf(stderr," .....plot_getrect %d %d %d %d\n", + // xx1, yy1, xx2, yy2); + if (xx1 < x1) + x1 = xx1; + if (yy1 < y1) + y1 = yy1; + if (xx2 > x2) + x2 = xx2; + if (yy2 > y2) + y2 = yy2; + //fprintf(stderr," ....plot_getrect %d %d %d %d\n", + // x1, y1, x2, y2); + } + } + //fprintf(stderr," >====plot_getrect %d %d %d %d\n", + // x1, y1, x2, y2); + } + } + //fprintf(stderr,"FINAL plot_getrect %d %d %d %d\n", x1, y1, x2, y2); + *xp1 = x1; + *yp1 = y1; + *xp2 = x2; + *yp2 = y2; +} + +static void old_plot_displace(t_gobj *z, t_glist *glist, + t_word *data, t_template *template, t_float basex, t_float basey, + int dx, int dy) +{ + /* not yet */ +} + +static void old_plot_select(t_gobj *z, t_glist *glist, + t_word *data, t_template *template, t_float basex, t_float basey, + int state) +{ + //fprintf(stderr,"plot_select %d\n", state); + /* not yet */ +} + +static void old_plot_activate(t_gobj *z, t_glist *glist, + t_word *data, t_template *template, t_float basex, t_float basey, + int state) +{ + /* not yet */ +} + +static void old_plot_vis(t_gobj *z, t_glist *glist, t_scalar *sc, + t_word *data, t_template *template, t_float basex, t_float basey, + int tovis) +{ + t_old_plot *x = (t_old_plot *)z; + /*// get the universal tag for all nested objects + t_canvas *tag = x->x_canvas; + while (tag->gl_owner) + { + tag = tag->gl_owner; + }*/ + + //fprintf(stderr,"===============plot %lx glist %lx glist_getcanvas %lx " + // "plot->x_obj %lx plot->x_canvas %lx " + // "glist_getcanvas(plot->x_canvas) %lx\n", + // (t_int)x, (t_int)glist, (t_int)glist_getcanvas(glist), + // (t_int)&x->x_obj, (t_int)x->x_canvas, (t_int)x->x_canvas->gl_owner); + + /* used for experimental disabling of drawing outside GOP bounds */ + int draw_me = 1; + int elemsize, yonset, wonset, xonset, i; + t_canvas *elemtemplatecanvas; + t_template *elemtemplate; + t_symbol *elemtemplatesym; + t_float linewidth, xloc, xinc, yloc, style, usexloc, xsum, yval, vis, + scalarvis; + t_symbol *symfill; + t_symbol *symoutline; + char outline[20]; + numbertocolor(fielddesc_getfloat(&x->x_outlinecolor, template, + data, 1), outline); + t_array *array; + int nelem; + char *elem; + t_fielddesc *xfielddesc, *yfielddesc, *wfielddesc; + /* even if the array is "invisible", if its visibility is + set by an instance variable you have to explicitly erase it, + because the flag could earlier have been on when we were getting + drawn. Rather than look to try to find out whether we're + visible we just do the erasure. At the TK level this should + cause no action because the tag matches nobody. LATER we + might want to optimize this somehow. Ditto the "vis()" routines + for other drawing instructions. */ + + if (old_plot_readownertemplate(x, data, template, + &elemtemplatesym, &array, &linewidth, &xloc, &xinc, &yloc, &style, + &vis, &scalarvis, &xfielddesc, &yfielddesc, &wfielddesc, &symfill, + &symoutline) || + ((vis == 0) && tovis) /* see above for 'tovis' */ + || array_getfields(elemtemplatesym, &elemtemplatecanvas, + &elemtemplate, &elemsize, xfielddesc, yfielddesc, wfielddesc, + &xonset, &yonset, &wonset)) + return; + nelem = array->a_n; + elem = (char *)array->a_vec; + + if (tovis) + { + /* check if old 3-digit color field is being used... */ + int dscolor = fielddesc_getfloat(&x->x_outlinecolor, template, data, 1); + if (dscolor != 0) + { + char outline[20]; + numbertocolor(dscolor, outline); + symoutline = gensym(outline); + } + if (symoutline == &s_) symoutline = gensym("#000000"); + if (symfill == &s_) symfill = gensym("#000000"); + if (style == PLOTSTYLE_POINTS || style == PLOTSTYLE_BARS) + { + symfill = style == PLOTSTYLE_POINTS ? symoutline : symfill; + t_float minyval = 1e20, maxyval = -1e20; + int ndrawn = 0; + sys_vgui(".x%lx.c create path { \\\n", glist_getcanvas(glist)); + for (xsum = basex + xloc, i = 0; i < nelem; i++) + { + t_float yval, xpix, ypix, nextxloc; + int ixpix, inextx; + + if (xonset >= 0) + { + usexloc = basex + xloc + + *(t_float *)((elem + elemsize * i) + xonset); + ixpix = glist_xtopixels(glist, + fielddesc_cvttocoord(xfielddesc, usexloc)); + inextx = ixpix + 2; + } + else + { + usexloc = xsum; + xsum += xinc; + ixpix = glist_xtopixels(glist, + fielddesc_cvttocoord(xfielddesc, usexloc)); + inextx = glist_xtopixels(glist, + fielddesc_cvttocoord(xfielddesc, xsum)); + } + + if (yonset >= 0) + yval = yloc + *(t_float *)((elem + elemsize * i) + yonset); + else yval = 0; + if (yval > maxyval) + maxyval = yval; + if (yval < minyval) + minyval = yval; + if (i == nelem-1 || inextx != ixpix) + { + int py2 = 0; + int border = 0; + if(style == PLOTSTYLE_POINTS) + py2 = (int)(glist_ytopixels(glist, + basey + fielddesc_cvttocoord(yfielddesc, maxyval)) + + linewidth) - 1; + else + { + /* this should probably be changed to anchor to the + y-minimum instead of the bottom of the graph. That + way the user can invert the y min/max to get a graph + anchored from the top */ + + if(glist->gl_isgraph && !glist->gl_havewindow) + { + int x1, y1, x2, y2; + graph_graphrect(&glist->gl_gobj, glist->gl_owner, + &x1, &y1, &x2, &y2); + py2 = y2; + border = 1; + } + } + //fprintf(stderr,"%f %f %f %f %f\n", basey, minyval, maxyval,glist->gl_y2,glist->gl_y1); + // with the following experimental code we can prevent drawing outside the gop window (preferred but needs to be further tested) + /*if (glist->gl_y2 > glist->gl_y1) + { + if (minyval >= glist->gl_y1 && maxyval <= glist->gl_y2) + draw_me = 1; + else + draw_me = 0; + } + else + { + if (minyval >= glist->gl_y2 && maxyval <= glist->gl_y1) + draw_me = 1; + else + draw_me = 0; + } + if (draw_me) + {*/ + //we subtract 1 from y to keep it in sync with + //the rest of the types of templates + /* This is the old, inefficient code that creates + a separate canvas item for each element... + sys_vgui(".x%lx.c create prect %d %d %d %d -fill %s " + "-stroke %s -strokewidth %d " + "-tags {.x%lx.x%lx.template%lx array}\n", + glist_getcanvas(glist), + ixpix, (int)glist_ytopixels(glist, + basey + fielddesc_cvttocoord(yfielddesc, minyval)) - 1, + inextx, py2, symfill->s_name, symoutline->s_name, + border, glist_getcanvas(glist), glist, data); + */ + + /* For efficiency, we make a single path item + for the trace or bargraph */ + int mex1 = ixpix; + int mey1 = (int)glist_ytopixels(glist, + basey + fielddesc_cvttocoord(yfielddesc, minyval)) - 1; + int mex2 = inextx; + int mey2 = py2; + sys_vgui("M %d %d H %d V %d H %d z \\\n", + mex1, mey1, mex2, mey2, mex1); + //} //part of experimental code above + ndrawn++; + minyval = 1e20; + maxyval = -1e20; + } + if (ndrawn > 2000 || ixpix >= 3000) break; + } + /* end of the path item from above */ + sys_vgui("} -fill %s -stroke %s -strokewidth %d " + "-tags {.x%lx.x%lx.template%lx array}\n", + symfill->s_name, symoutline->s_name, + style == PLOTSTYLE_POINTS ? 0 : 1, + glist_getcanvas(glist), glist, data); + } + else + { + //char outline[20]; + int lastpixel = -1, ndrawn = 0; + t_float yval = 0, wval = 0, xpix; + int ixpix = 0; + /* draw the trace */ + //numbertocolor(fielddesc_getfloat(&x->x_outlinecolor, template, + // data, 1), outline); + if (wonset >= 0) + { + /* found "w" field which controls linewidth. The trace is + a filled polygon with 2n points. */ + sys_vgui(".x%lx.c create ppolygon \\\n", + glist_getcanvas(glist)); + + for (i = 0, xsum = xloc; i < nelem; i++) + { + if (xonset >= 0) + usexloc = xloc + *(t_float *)((elem + elemsize * i) + + xonset); + else usexloc = xsum, xsum += xinc; + if (yonset >= 0) + yval = *(t_float *)((elem + elemsize * i) + yonset); + else yval = 0; + wval = *(t_float *)((elem + elemsize * i) + wonset); + xpix = glist_xtopixels(glist, + basex + fielddesc_cvttocoord(xfielddesc, usexloc)); + ixpix = xpix + 0.5; + if (xonset >= 0 || ixpix != lastpixel) + { + sys_vgui("%d %f \\\n", ixpix, + glist_ytopixels(glist, + basey + fielddesc_cvttocoord(yfielddesc, + yloc + yval) - + fielddesc_cvttocoord(wfielddesc,wval))); + ndrawn++; + } + lastpixel = ixpix; + if (ndrawn >= 1000) goto ouch; + } + lastpixel = -1; + for (i = nelem-1; i >= 0; i--) + { + t_float usexloc; + if (xonset >= 0) + usexloc = xloc + *(t_float *)((elem + elemsize * i) + + xonset); + else xsum -= xinc, usexloc = xsum; + if (yonset >= 0) + yval = *(t_float *)((elem + elemsize * i) + yonset); + else yval = 0; + wval = *(t_float *)((elem + elemsize * i) + wonset); + xpix = glist_xtopixels(glist, + basex + fielddesc_cvttocoord(xfielddesc, usexloc)); + ixpix = xpix + 0.5; + if (xonset >= 0 || ixpix != lastpixel) + { + sys_vgui("%d %f \\\n", ixpix, glist_ytopixels(glist, + basey + yloc + fielddesc_cvttocoord(yfielddesc, + yval) + + fielddesc_cvttocoord(wfielddesc, wval))); + ndrawn++; + } + lastpixel = ixpix; + if (ndrawn >= 1000) goto ouch; + } + /* TK will complain if there aren't at least 3 points. + There should be at least two already. */ + if (ndrawn < 4) + { + sys_vgui("%d %f \\\n", ixpix + 10, glist_ytopixels(glist, + basey + yloc + fielddesc_cvttocoord(yfielddesc, + yval) + + fielddesc_cvttocoord(wfielddesc, wval))); + sys_vgui("%d %f \\\n", ixpix + 10, glist_ytopixels(glist, + basey + yloc + fielddesc_cvttocoord(yfielddesc, + yval) - + fielddesc_cvttocoord(wfielddesc, wval))); + } + ouch: + sys_vgui(" -strokewidth 1 -fill %s -stroke %s \\\n", + symfill->s_name, symoutline->s_name); + // this doesn't work with tkpath... + //if (style == PLOTSTYLE_BEZ) sys_vgui("-smooth 1 \\\n"); + + sys_vgui("-tags {.x%lx.x%lx.template%lx scalar%lx}\n", + glist_getcanvas(glist), glist, data, sc); + } + else if (linewidth > 0) + { + /* no "w" field. If the linewidth is positive, draw a + segmented line with the requested width; otherwise don't + draw the trace at all. */ + sys_vgui(".x%lx.c create polyline \\\n", glist_getcanvas(glist)); + + for (xsum = xloc, i = 0; i < nelem; i++) + { + t_float usexloc; + if (xonset >= 0) + usexloc = xloc + *(t_float *)((elem + elemsize * i) + + xonset); + else usexloc = xsum, xsum += xinc; + if (yonset >= 0) + yval = *(t_float *)((elem + elemsize * i) + yonset); + else yval = 0; + xpix = glist_xtopixels(glist, + basex + fielddesc_cvttocoord(xfielddesc, usexloc)); + ixpix = xpix + 0.5; + if (xonset >= 0 || ixpix != lastpixel) + { + sys_vgui("%d %f \\\n", ixpix, + glist_ytopixels(glist, + basey + yloc + fielddesc_cvttocoord(yfielddesc, + yval))); + ndrawn++; + } + lastpixel = ixpix; + if (ndrawn >= 1000) break; + } + /* TK will complain if there aren't at least 2 points... */ + if (ndrawn == 0) sys_vgui("0 0 0 0 \\\n"); + else if (ndrawn == 1) sys_vgui("%d %f \\\n", ixpix + 10, + glist_ytopixels(glist, basey + yloc + + fielddesc_cvttocoord(yfielddesc, yval))); + + //sys_vgui("-strokewidth %f \\\n", linewidth); + //sys_vgui("-fill %s \\\n", outline); + sys_vgui("-strokewidth %f -stroke %s \\\n", linewidth, symoutline->s_name); + //sys_vgui("-fill %s \\\n", symoutline->s_name); + //if (style == PLOTSTYLE_BEZ) sys_vgui("-smooth 1 \\\n"); //this doesn't work with tkpath + + sys_vgui("-tags {.x%lx.x%lx.template%lx scalar%lx}\n", glist_getcanvas(glist), glist, data,sc); + } + } + /* make sure the array drawings are behind the graph */ + sys_vgui(".x%lx.c lower plot%lx graph%lx\n", glist_getcanvas(glist), + data, glist); + + /* We're done with the outline; now draw all the points. + This code is inefficient since the template has to be + searched for drawing instructions for every last point. */ + if (scalarvis != 0) + { + for (xsum = xloc, i = 0; i < nelem; i++) + { + t_float usexloc, useyloc; + t_gobj *y; + if (xonset >= 0) + usexloc = /* basex */ + xloc + + *(t_float *)((elem + elemsize * i) + xonset); + else usexloc = /* basex */ + xsum, xsum += xinc; + if (yonset >= 0) + yval = *(t_float *)((elem + elemsize * i) + yonset); + else yval = 0; + useyloc = /* basey */ + yloc + + fielddesc_cvttocoord(yfielddesc, yval); + for (y = elemtemplatecanvas->gl_list; y; y = y->g_next) + { + t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd); + if (!wb) continue; + (*wb->w_parentvisfn)(y, glist, sc, + (t_word *)(elem + elemsize * i), + elemtemplate, usexloc, useyloc, tovis); + } + } + } + if (!glist_istoplevel(glist)) + { + t_canvas *gl = glist_getcanvas(glist); + char objtag[64]; + sprintf(objtag, ".x%lx.x%lx.template%lx", + (t_int)gl, (t_int)glist, (t_int)data); + canvas_restore_original_position(gl, (t_gobj *)glist, objtag, -1); + } + /* + sys_vgui(".x%lx.c lower .x%lx.x%lx.plot%lx %s\n", + glist_getcanvas(glist), glist_getcanvas(glist), glist, data, + rtext_gettag(glist_findrtext(glist_getcanvas(glist), + &glist->gl_obj))); + sys_vgui(".x%lx.c raise .x%lx.x%lx.plot%lx %s\n", + glist_getcanvas(glist), glist_getcanvas(glist), glist, data, + rtext_gettag(glist_findrtext(glist_getcanvas(glist), + &glist->gl_obj))); + */ + } + else + { + /* un-draw the individual points */ + //fprintf(stderr,"plot_vis UNVIS\n"); + if (scalarvis != 0) + { + int i; + for (i = 0; i < nelem; i++) + { + t_gobj *y; + for (y = elemtemplatecanvas->gl_list; y; y = y->g_next) + { + t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd); + if (!wb) continue; + (*wb->w_parentvisfn)(y, glist, sc, + (t_word *)(elem + elemsize * i), elemtemplate, + 0, 0, 0); + } + } + } + /* and then the trace */ + sys_vgui(".x%lx.c delete .x%lx.x%lx.template%lx\n", + glist_getcanvas(glist), glist_getcanvas(glist), glist, data); + } +} + +static int old_plot_click(t_gobj *z, t_glist *glist, + t_word *data, t_template *template, t_scalar *sc, t_array *ap, + t_float basex, t_float basey, + int xpix, int ypix, int shift, int alt, int dbl, int doit) +{ + //fprintf(stderr,"plot_click %lx %lx %f %f %d %d\n", + // (t_int)z, (t_int)glist, basex, basey, xpix, ypix); + t_old_plot *x = (t_old_plot *)z; + t_symbol *elemtemplatesym; + t_float linewidth, xloc, xinc, yloc, style, vis, scalarvis; + t_array *array; + t_fielddesc *xfielddesc, *yfielddesc, *wfielddesc; + t_symbol *symfillcolor; + t_symbol *symoutlinecolor; + + if (!old_plot_readownertemplate(x, data, template, + &elemtemplatesym, &array, &linewidth, &xloc, &xinc, &yloc, &style, + &vis, &scalarvis, + &xfielddesc, &yfielddesc, &wfielddesc, &symfillcolor, &symoutlinecolor) + && (vis != 0)) + { + //fprintf(stderr," ->array_doclick\n"); + return (array_doclick(array, glist, sc, ap, + elemtemplatesym, + linewidth, basex + xloc, xinc, basey + yloc, scalarvis, + xfielddesc, yfielddesc, wfielddesc, + xpix, ypix, shift, alt, dbl, doit)); + } + else return (0); +} + +static void old_plot_free(t_plot *x) +{ + //fprintf(stderr,"plot_free\n"); + //sys_queuegui(x->x_canvas, 0, canvas_redrawallfortemplatecanvas); + /* decrement variable of the template + to prevent transform as that would + make arrays break their hitboxes + and all kinds of other bad stuff */ + t_template *t = template_findbyname( + canvas_makebindsym(x->x_canvas->gl_name) + ); + if (t) + { + t->t_transformable--; + //fprintf(stderr,"plot_free > template:%lx(%s) transform:%d\n", + // (t_int)t, canvas_makebindsym(x->x_canvas->gl_name)->s_name, + // t->t_transformable); + } +} + +t_parentwidgetbehavior old_plot_widgetbehavior = +{ + old_plot_getrect, + old_plot_displace, + old_plot_select, + old_plot_activate, + old_plot_vis, + old_plot_click, +}; + +static void old_plot_setup(void) +{ + old_plot_class = class_new(gensym("old_plot"), (t_newmethod)old_plot_new, + (t_method)old_plot_free, sizeof(t_old_plot), 0, A_GIMME, 0); + class_setdrawcommand(old_plot_class); + class_addfloat(old_plot_class, old_plot_float); + class_setparentwidget(old_plot_class, &old_plot_widgetbehavior); +} + /* ---------------- drawnumber: draw a number (or symbol) ---------------- */ /* @@ -5675,6 +6503,8 @@ t_template *template_findbydrawcommand(t_gobj *g) c = ((t_drawsymbol *)g)->x_canvas; else if (g->g_pd == drawimage_class) c = ((t_drawimage *)g)->x_canvas; + else if (g->g_pd == plot_class) + c = ((t_plot *)g)->x_canvas; else return (0); t_template *tmpl; t_symbol *s1 = gensym("struct"); @@ -5703,6 +6533,7 @@ void g_template_setup(void) curve_setup(); draw_setup(); plot_setup(); + old_plot_setup(); drawnumber_setup(); drawsymbol_setup(); drawimage_setup(); diff --git a/pd/src/g_text.c b/pd/src/g_text.c index 2565db5cb..7203cecba 100644 --- a/pd/src/g_text.c +++ b/pd/src/g_text.c @@ -137,7 +137,10 @@ static void canvas_objtext(t_glist *gl, int xpix, int ypix, { t_symbol *templatesym = canvas_makebindsym(atom_getsymbol(scalar_at)); - if (template_findbyname(templatesym)) + t_template *tmpl = template_findbyname(templatesym); + if (template_findbyname(templatesym) && + template_cancreate(tmpl) && + template_hasxy(tmpl)) { //post("Hmm, found a scalar from struct %s... ", // templatesym->s_name); diff --git a/pd/src/m_pd.h b/pd/src/m_pd.h index 1fb341904..6d59328d5 100644 --- a/pd/src/m_pd.h +++ b/pd/src/m_pd.h @@ -11,7 +11,7 @@ extern "C" { #define PD_MAJOR_VERSION 0 #define PD_MINOR_VERSION 42 #define PD_BUGFIX_VERSION 7 -#define PD_TEST_VERSION "20131117" +#define PD_TEST_VERSION "20140319" #define PDL2ORK /* old name for "MSW" flag -- we have to take it for the sake of many old -- GitLab