diff --git a/pd/src/g_array.c b/pd/src/g_array.c index 3c06df4213fcf2522d99111c223cfc8017e7e0f5..7287a3414ebd7b2c40e2ffb3478bc86678266f7c 100644 --- a/pd/src/g_array.c +++ b/pd/src/g_array.c @@ -395,6 +395,7 @@ t_garray *graph_array(t_glist *gl, t_symbol *s, int argc, t_atom *argv) /* called from array menu item to create a new one */ void canvas_menuarray(t_glist *canvas) { + if (canvas_hasarray(canvas)) return; t_glist *x = (t_glist *)canvas; pd_vmess(&x->gl_pd, gensym("editmode"), "i", 1); char cmdbuf[200]; @@ -766,6 +767,7 @@ static void array_motion(void *z, t_floatarg dx, t_floatarg dy) { array_motion_xcumulative += dx * array_motion_xperpix; array_motion_ycumulative += dy * array_motion_yperpix; + //fprintf(stderr,"array_motion %f %f %f %f\n", array_motion_xcumulative, array_motion_ycumulative, dx, dy); // used to set up boundaries and update sends accordingly t_glist *graph = NULL; @@ -873,7 +875,7 @@ static int array_doclick_element(t_array *array, t_glist *glist, t_fielddesc *xfield, t_fielddesc *yfield, t_fielddesc *wfield, int xpix, int ypix, int shift, int alt, int dbl, int doit) { - //fprintf(stderr,"array_doclick_element %d\n", doit); + //fprintf(stderr,"array_doclick_element linewidth%f xloc%f xinc%f yloc%f xpix%d ypix%d doit%d\n", linewidth, xloc, xinc, yloc, xpix, ypix, doit); t_canvas *elemtemplatecanvas; t_template *elemtemplate; int elemsize, yonset, wonset, xonset, i, incr, hit; @@ -917,7 +919,7 @@ int array_doclick(t_array *array, t_glist *glist, t_scalar *sc, t_array *ap, t_fielddesc *xfield, t_fielddesc *yfield, t_fielddesc *wfield, int xpix, int ypix, int shift, int alt, int dbl, int doit) { - //fprintf(stderr,"array_doclick %d\n", doit); + //fprintf(stderr,"array_doclick linewidth%f xloc%f xinc%f yloc%f xpix%d ypix%d doit%d\n", linewidth, xloc, xinc, yloc, xpix, ypix, doit); t_canvas *elemtemplatecanvas; t_template *elemtemplate; int elemsize, yonset, wonset, xonset, i; @@ -935,7 +937,7 @@ int array_doclick(t_array *array, t_glist *glist, t_scalar *sc, t_array *ap, array_getcoordinate(glist, (char *)(array->a_vec) + i * elemsize, xonset, yonset, wonset, i, xloc, yloc, xinc, xfield, yfield, wfield, &pxpix1, &pxpix2, &pypix, &pwpix); - //fprintf(stderr," array_getcoordinate %d: pxpix:%f pypix:%f pwpix:%f dx:%f dy:%f elemsize:%d yonset:%d wonset:%d xonset:%d xloc:%f yloc:%f xinc:%f\n", i, pxpix, pypix, pwpix, dx, dy, elemsize, yonset, wonset, xonset, xloc, yloc, xinc); + //fprintf(stderr," array_getcoordinate %d: pxpix1:%f pxpix2:%f pypix:%f pwpix:%f dx:%f dy:%f elemsize:%d yonset:%d wonset:%d xonset:%d xloc:%f yloc:%f xinc:%f\n", i, pxpix1, pxpix2, pypix, pwpix, dx, dy, elemsize, yonset, wonset, xonset, xloc, yloc, xinc); if (pwpix < 4) pwpix = 4; if (xpix >= (int)pxpix1 && xpix <= (int)pxpix2 && @@ -1072,6 +1074,7 @@ int array_doclick(t_array *array, t_glist *glist, t_scalar *sc, t_array *ap, } if (xonset >= 0) { + //fprintf(stderr, " xonset >=0\n"); array_motion_xfield = xfield; array_motion_xcumulative = fielddesc_getcoord(xfield, array_motion_template, @@ -1083,6 +1086,7 @@ int array_doclick(t_array *array, t_glist *glist, t_scalar *sc, t_array *ap, } else { + //fprintf(stderr, " !(xonset >=0)\n"); array_motion_xfield = 0; array_motion_xcumulative = 0; array_motion_wp = (t_word *)elem; @@ -1094,6 +1098,7 @@ int array_doclick(t_array *array, t_glist *glist, t_scalar *sc, t_array *ap, } if (array_motion_fatten) { + //fprintf(stderr, " motion_fatten\n"); array_motion_yfield = wfield; array_motion_ycumulative = fielddesc_getcoord(wfield, array_motion_template, @@ -1102,20 +1107,40 @@ int array_doclick(t_array *array, t_glist *glist, t_scalar *sc, t_array *ap, } else if (yonset >= 0) { + //fprintf(stderr, " yonset >=0\n"); array_motion_yfield = yfield; array_motion_ycumulative = fielddesc_getcoord(yfield, array_motion_template, (t_word *)(elem + i * elemsize), 1); /* *(t_float *)((elem + elemsize * i) + yonset); */ - if (array_joc) - array_motion(0, 0, ypix - pypix); + //if (array_joc) { + // we do cursor detection based on the kind of a graph. + // (e.g. 3-point PLOYSTYLE_POINTS creates a graph that has 4 delimiting points, + // while a 3-point PLOTSTYLE_POLY creates a graph that has only 3 delimiting points) + // This, therefore takes into account whether we should count the center point + // of a bar or the starting point (poly) as our reference + // TODO: see if we can reimplement Bezier curves + if (array_garray->x_style == PLOTSTYLE_POLY || array_garray->x_style == PLOTSTYLE_BEZ) + array_motion(0, xpix - pxpix1, ypix - pypix); + else + array_motion(0, (xpix - (pxpix1 + (pxpix2 - pxpix1)/2)), ypix - pypix); + //} + //else { + // array_motion(0, (xpix - (pxpix1 + (pxpix2 - pxpix1)/2)), ypix - pypix); + //} + //fprintf(stderr, "xpix:%d pxpix1:%f half:%f result:%f\n", xpix, pxpix1, (pxpix2-pxpix1)/2, xpix - (pxpix1 + (pxpix2 - pxpix1)/2)); } else { + //fprintf(stderr, " else 0\n"); array_motion_yfield = 0; array_motion_ycumulative = 0; } + //fprintf(stderr," glist_grab %d %d\n", xpix, ypix); glist_grab(glist, 0, array_motion, 0, xpix, ypix); + //fprintf(stderr," VALUES: array_motion_initx:%f array_motion_lastx:%d array_motion_xperpix:%f array_motion_xcumulative:%f\n", array_motion_initx, array_motion_lastx, array_motion_xperpix, array_motion_xcumulative); + //fprintf(stderr," array_getcoordinate %d: pxpix1:%f pxpix2:%f pypix:%f pwpix:%f dx:%f dy:%f elemsize:%d yonset:%d wonset:%d xonset:%d xloc:%f yloc:%f xinc:%f\n", i, pxpix1, pxpix2, pypix, pwpix, dx, dy, elemsize, yonset, wonset, xonset, xloc, yloc, xinc); + } if (alt) { @@ -1135,12 +1160,12 @@ int array_doclick(t_array *array, t_glist *glist, t_scalar *sc, t_array *ap, static void array_getrect(t_array *array, t_glist *glist, int *xp1, int *yp1, int *xp2, int *yp2) { - //fprintf(stderr,"array getrect\n"); + //fprintf(stderr,"array getrect %d %d\n", glist_istoplevel(glist), (array_joc != 0 ? 1 : 0)); t_float x1 = 0x7fffffff, y1 = 0x7fffffff, x2 = -0x7fffffff, y2 = -0x7fffffff; t_canvas *elemtemplatecanvas; t_template *elemtemplate; int elemsize, yonset, wonset, xonset, i; - + if (!array_getfields(array->a_templatesym, &elemtemplatecanvas, &elemtemplate, &elemsize, 0, 0, 0, &xonset, &yonset, &wonset)) { @@ -1181,6 +1206,7 @@ static void array_getrect(t_array *array, t_glist *glist, static void garray_getrect(t_gobj *z, t_glist *glist, int *xp1, int *yp1, int *xp2, int *yp2) { + //fprintf(stderr,"garray_getrect\n"); t_garray *x = (t_garray *)z; gobj_getrect(&x->x_scalar->sc_gobj, glist, xp1, yp1, xp2, yp2); } diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c index 4a8f9790bfe624de3b6470e871c88ce63551036c..20c57e5a8065d86696807c049977c8ca5a4bd0ac 100644 --- a/pd/src/g_canvas.c +++ b/pd/src/g_canvas.c @@ -575,6 +575,7 @@ extern int we_are_undoing; /* call glist_addglist from a Pd message */ void glist_glist(t_glist *g, t_symbol *s, int argc, t_atom *argv) { + if (canvas_hasarray(g)) return; pd_vmess(&g->gl_pd, gensym("editmode"), "i", 1); t_symbol *sym = atom_getsymbolarg(0, argc, argv); /* if we wish to put a graph where the mouse is we need to replace bogus name */ diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h index fa7b9d56f05314287af040b01a8be89f2330b732..89e582ebfd8cd982f4acf99ea0dfa6f4fba99de8 100644 --- a/pd/src/g_canvas.h +++ b/pd/src/g_canvas.h @@ -560,6 +560,7 @@ EXTERN int canvas_hitbox(t_canvas *x, t_gobj *y, int xpos, int ypos, EXTERN t_gobj *canvas_findhitbox(t_canvas *x, int xpos, int ypos, int *x1p, int *y1p, int *x2p, int *y2p); EXTERN int canvas_setdeleting(t_canvas *x, int flag); +EXTERN int canvas_hasarray(t_canvas *x); /* ---- for parsing @pd_extra and other sys paths in filenames --------------------- */ diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c index 900977287b3e4cf6b0ece5f0d3d554682dd0e223..ea840b3c02c7d87658d38be8a8165ecdb66e944f 100644 --- a/pd/src/g_editor.c +++ b/pd/src/g_editor.c @@ -2385,9 +2385,10 @@ void canvas_setgraph(t_glist *x, int flag, int nogoprect) } if (hasarray) x->gl_hidetext = 1; - if (!nogoprect && !x->gl_goprect) + if (!nogoprect && !x->gl_goprect && !hasarray) { - /* Ivica Ico Bukvic 5/16/10 <ico@bukvic.net> */ + // Ivica Ico Bukvic 5/16/10 <ico@bukvic.net> + // this draws gop immediately when enabled x->gl_goprect = 1; } if (glist_isvisible(x) && x->gl_goprect) { @@ -6399,6 +6400,10 @@ void glob_pastetext(void *dummy, t_symbol *s, int ac, t_atom *av) void canvas_editmode(t_canvas *x, t_floatarg fyesplease) { //fprintf(stderr,"canvas_editmode %f\n", fyesplease); + + //first check if this is a canvas hosting an array and if so refuse to add any further objects + if (canvas_hasarray(x)) return; + int yesplease = fyesplease; if (yesplease && x->gl_edit) { //if (x->gl_edit && glist_isvisible(x) && glist_istoplevel(x)) diff --git a/pd/src/g_graph.c b/pd/src/g_graph.c index 81331f16819277ac3f14eae5e6250dccdc216446..8c34610a9e55cecc33879d76f0e5bd1b1984ed8f 100644 --- a/pd/src/g_graph.c +++ b/pd/src/g_graph.c @@ -82,6 +82,18 @@ int canvas_setdeleting(t_canvas *x, int flag) return (ret); } + /* check if canvas has an array and return 1, otherwise return 0 + this is used to prevent creation of new objects in an array window */ +int canvas_hasarray(t_canvas *x) { + t_gobj *g = x->gl_list; + int hasarray = 0; + while (g) { + if (pd_class(&g->g_pd) == garray_class) hasarray = 1; + g = g->g_next; + } + return(hasarray); +} + /* JMZ: emit a closebang message */ void canvas_closebang(t_canvas *x); diff --git a/pd/src/g_scalar.c b/pd/src/g_scalar.c index 1d1d9472bfa3ed1866b7e51187e09d3026b6a3f5..b5057fe620c4a6b0730fd2baea2c78f623366cda 100644 --- a/pd/src/g_scalar.c +++ b/pd/src/g_scalar.c @@ -152,44 +152,56 @@ void scalar_getbasexy(t_scalar *x, t_float *basex, t_float *basey) *basey = template_getfloat(template, gensym("y"), x->sc_vec, 0); } +extern int array_joc; + static void scalar_getrect(t_gobj *z, t_glist *owner, int *xp1, int *yp1, int *xp2, int *yp2) { - //fprintf(stderr,"scalar_getrect\n"); + //fprintf(stderr,"scalar_getrect %d\n", array_joc); t_scalar *x = (t_scalar *)z; t_template *template = template_findbyname(x->sc_template); t_canvas *templatecanvas = template_findcanvas(template); int x1 = 0x7fffffff, x2 = -0x7fffffff, y1 = 0x7fffffff, y2 = -0x7fffffff; t_gobj *y; t_float basex, basey; - scalar_getbasexy(x, &basex, &basey); - /* if someone deleted the template canvas, we're just a point */ - if (!templatecanvas) - { - //fprintf(stderr,"...point\n"); - x1 = x2 = glist_xtopixels(owner, basex); - y1 = y2 = glist_ytopixels(owner, basey); + + // EXPERIMENTAL: we assume that entire canvas is withing the rectangle--this is for arrays + // with "jump on click" enabled TODO: test for other regressions (there shouuld not be any + // provided the global variable array_joc is properly maintained) + if (glist_istoplevel(owner) && array_joc) { + x1 = -0x7fffffff, y1 = -0x7fffffff, x2 = 0x7fffffff, y2 = 0x7fffffff; } - else - { - x1 = y1 = 0x7fffffff; - x2 = y2 = -0x7fffffff; - for (y = templatecanvas->gl_list; y; y = y->g_next) + + else { + scalar_getbasexy(x, &basex, &basey); + /* if someone deleted the template canvas, we're just a point */ + if (!templatecanvas) + { + //fprintf(stderr,"...point\n"); + x1 = x2 = glist_xtopixels(owner, basex); + y1 = y2 = glist_ytopixels(owner, basey); + } + else { - t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd); - int nx1, ny1, nx2, ny2; - if (!wb) continue; - (*wb->w_parentgetrectfn)(y, owner, - x->sc_vec, template, basex, basey, - &nx1, &ny1, &nx2, &ny2); - if (nx1 < x1) x1 = nx1; - if (ny1 < y1) y1 = ny1; - if (nx2 > x2) x2 = nx2; - if (ny2 > y2) y2 = ny2; - //fprintf(stderr," ====scalar_getrect x1 %d y1 %d x2 %d y2 %d\n", x1, y1, x2, y2); + x1 = y1 = 0x7fffffff; + x2 = y2 = -0x7fffffff; + for (y = templatecanvas->gl_list; y; y = y->g_next) + { + t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd); + int nx1, ny1, nx2, ny2; + if (!wb) continue; + (*wb->w_parentgetrectfn)(y, owner, + x->sc_vec, template, basex, basey, + &nx1, &ny1, &nx2, &ny2); + if (nx1 < x1) x1 = nx1; + if (ny1 < y1) y1 = ny1; + if (nx2 > x2) x2 = nx2; + if (ny2 > y2) y2 = ny2; + //fprintf(stderr," ====scalar_getrect x1 %d y1 %d x2 %d y2 %d\n", x1, y1, x2, y2); + } + if (x2 < x1 || y2 < y1) + x1 = y1 = x2 = y2 = 0; } - if (x2 < x1 || y2 < y1) - x1 = y1 = x2 = y2 = 0; } //fprintf(stderr,"FINAL scalar_getrect x1 %d y1 %d x2 %d y2 %d\n", x1, y1, x2, y2); *xp1 = x1; diff --git a/pd/src/g_text.c b/pd/src/g_text.c index febe69afd53b47bfa84bb22e8f9eab214365bd94..60c502d07a64b388be474985a965c710e5318dbb 100644 --- a/pd/src/g_text.c +++ b/pd/src/g_text.c @@ -52,6 +52,7 @@ extern void glob_preset_node_list_seek_hub(void); void glist_text(t_glist *gl, t_symbol *s, int argc, t_atom *argv) { + if (canvas_hasarray(gl)) return; t_text *x = (t_text *)pd_new(text_class); t_atom at; x->te_width = 0; /* don't know it yet. */ @@ -269,6 +270,7 @@ EXTERN int connect_exception; void canvas_obj(t_glist *gl, t_symbol *s, int argc, t_atom *argv) { //fprintf(stderr,"canvas_obj\n"); + if (canvas_hasarray(gl)) return; t_text *x; if (argc >= 2) { @@ -310,6 +312,7 @@ extern void glist_setlastxy(t_glist *gl, int xval, int yval); /* invoked from tcl/tk: abstraction_name x_offset y_offset */ void canvas_obj_abstraction_from_menu(t_glist *gl, t_symbol *s, int argc, t_atom *argv) { + if (canvas_hasarray(gl)) return; //fprintf(stderr,"canvas_abstraction_from_menu\n"); //t_text *x; t_gobj *y; @@ -348,6 +351,7 @@ void canvas_obj_abstraction_from_menu(t_glist *gl, t_symbol *s, int argc, t_atom /* iemlib */ void canvas_iemguis(t_glist *gl, t_symbol *guiobjname) { + if (canvas_hasarray(gl)) return; //fprintf(stderr,"canvas_iemguis\n"); t_atom at; t_binbuf *b = binbuf_new(); @@ -629,6 +633,7 @@ static void message_free(t_message *x) void canvas_msg(t_glist *gl, t_symbol *s, int argc, t_atom *argv) { + if (canvas_hasarray(gl)) return; /*fprintf(stderr,"canvas_msg\n"); int i = 0; while(i < argc) { @@ -1093,6 +1098,7 @@ static void gatom_vis(t_gobj *z, t_glist *glist, int vis) void canvas_atom(t_glist *gl, t_atomtype type, t_symbol *s, int argc, t_atom *argv) { + if (canvas_hasarray(gl)) return; //fprintf(stderr,"canvas_atom\n"); t_gatom *x = (t_gatom *)pd_new(gatom_class); t_atom at;