From 55cb5c09f0fc4cf45de56d3ce4bae9493f56dca3 Mon Sep 17 00:00:00 2001 From: Jonathan Wilkes <jon.w.wilkes@gmail.com> Date: Sun, 29 Oct 2017 15:23:52 -0400 Subject: [PATCH] make it possible to update attributes for an array element without redrawing --- pd/src/g_scalar.c | 78 +++++++++++++++++++++++++++++++++++--------- pd/src/g_template.c | 22 ++++++++----- pd/src/g_traversal.c | 10 +++--- 3 files changed, 82 insertions(+), 28 deletions(-) diff --git a/pd/src/g_scalar.c b/pd/src/g_scalar.c index 7432aa57e..059f3acfd 100644 --- a/pd/src/g_scalar.c +++ b/pd/src/g_scalar.c @@ -780,32 +780,36 @@ extern void svg_register_events(t_gobj *z, t_canvas *c, t_scalar *sc, t_template *template, t_word *data); static void scalar_group_configure(t_scalar *x, t_glist *owner, - t_template *template, t_glist *gl, t_glist *parent) + t_template *template, t_word *data, t_glist *gl, t_glist *parent) { t_gobj *y; char tagbuf[MAXPDSTRING]; sprintf(tagbuf, "dgroup%lx.%lx", (long unsigned int)gl, - (long unsigned int)x->sc_vec); + (long unsigned int)data); char parentbuf[MAXPDSTRING]; - sprintf(parentbuf, "dgroup%lx.%lx", (long unsigned int)parent, - (long unsigned int)x->sc_vec); + /* check if we're in an array-- really need to see if we can just + get rid of the different tag names for arrays... */ + sprintf(parentbuf, "%s%lx.%lx", (x->sc_vec == data) ? "dgroup" : "scelem", + (long unsigned int)parent, + (long unsigned int)data); gui_start_vmess("gui_draw_configure_all", "xs", glist_getcanvas(owner), tagbuf); - svg_grouptogui(gl, template, x->sc_vec); + svg_grouptogui(gl, template, data); gui_end_vmess(); - svg_register_events((t_gobj *)gl, owner, x, template, x->sc_vec); + svg_register_events((t_gobj *)gl, owner, x, template, data); for (y = gl->gl_list; y; y = y->g_next) { if (pd_class(&y->g_pd) == canvas_class && ((t_glist *)y)->gl_svg) { - scalar_group_configure(x, owner, template, (t_glist *)y, gl); + scalar_group_configure(x, owner, template, data, (t_glist *)y, gl); } t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd); if (!wb) continue; - //(*wb->w_parentvisfn)(y, owner, gl, x, x->sc_vec, template, + //(*wb->w_parentvisfn)(y, owner, gl, x, data, template, // 0, 0, vis); - svg_parentwidgettogui(y, x, owner, x->sc_vec, template); + svg_parentwidgettogui(y, x, owner, data, template); + svg_register_events(y, owner, x, template, data); } } @@ -848,7 +852,7 @@ void scalar_doconfigure(t_gobj *xgobj, t_glist *owner) if (pd_class(&y->g_pd) == canvas_class && ((t_glist *)y)->gl_svg) { - scalar_group_configure(x, owner, template, + scalar_group_configure(x, owner, template, x->sc_vec, (t_glist *)y, templatecanvas); } continue; @@ -856,6 +860,7 @@ void scalar_doconfigure(t_gobj *xgobj, t_glist *owner) //(*wb->w_parentvisfn)(y, owner, 0, x, x->sc_vec, template, // basex, basey, vis); svg_parentwidgettogui(y, x, owner, x->sc_vec, template); + svg_register_events(y, owner, x, template, x->sc_vec); } if (glist_isselected(owner, &x->sc_gobj)) { @@ -873,6 +878,47 @@ void scalar_configure(t_scalar *x, t_glist *owner) sys_queuegui(x, owner, scalar_doconfigure); } +extern int is_plot_class(t_gobj *y); +void array_configure(t_scalar *x, t_glist *owner, t_array *a, t_word *data) +{ + t_template *template = template_findbyname(x->sc_template); + t_template *elemtemplate = template_findbyname(a->a_templatesym); + t_canvas *templatecanvas = template_findcanvas(template); + t_canvas *elemtemplatecanvas = template_findcanvas(elemtemplate); + t_gobj *y; + + for (y = templatecanvas->gl_list; y; y = y->g_next) + { + t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd); + if (wb && is_plot_class(y)) + { + scalar_redraw(x, owner); + return; + } + } + /* If no plot widgets, it is now safe to just configure the individual + array elements. */ + for (y = elemtemplatecanvas->gl_list; y; y = y->g_next) + { + t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd); + if (!wb) + { + /* check subpatches for more drawing commands. + (Optimized to only search [group] subpatches) */ + if (pd_class(&y->g_pd) == canvas_class && + ((t_glist *)y)->gl_svg) + { + scalar_group_configure(x, owner, template, data, + (t_glist *)y, elemtemplatecanvas); + } + continue; + } + svg_parentwidgettogui(y, x, owner, data, elemtemplate); + svg_register_events(y, owner, x, elemtemplate, data); + } + +} + static void scalar_groupvis(t_scalar *x, t_glist *owner, t_template *template, t_glist *gl, t_glist *parent, int vis) { @@ -908,27 +954,27 @@ static void scalar_groupvis(t_scalar *x, t_glist *owner, t_template *template, } } -/* At present, scalars have a three-level hierarchy in tkpath, +/* At present, scalars have a three-level hierarchy in the gui, with two levels accessible by the user from within Pd: scalar - ".scalar%lx", x->sc_vec - | tkpath group with matrix derived from x/y fields, + | <g> with matrix derived from x/y fields, | gop basexy, and gop scaling values. This group is | not configurable by the user. This means that the - | [draw group] below can ignore basexy and gop junk + | a [draw g] below can ignore basexy and gop junk | when computing the transform matrix. v group - ".dgroup%lx.%lx", templatecanvas, x->sc_vec | group used as parent for all the toplevel drawing | commands of the scalar (i.e., the ones located on | the same canvas as the [struct]). Its matrix and - | options aren't yet accessible by the user. + | options aren't accessible by the user. v (draw - ".draw%lx.%lx", (t_draw *ptr), x->sc_vec - | the actual drawing command: rectangle, path, etc. + | the actual drawing command: rectangle, path, g, etc. or Each has its own matrix and options which can set scelem with messages to the corresponding [draw] object. or - ds arrays can nest arbitrarily deep. Scelem is for - group) data structure arrays. group is for more groups. + group) data structure arrays. group is for [draw g] and [draw svg] | v etc. diff --git a/pd/src/g_template.c b/pd/src/g_template.c index dec213da8..1ccc2359e 100644 --- a/pd/src/g_template.c +++ b/pd/src/g_template.c @@ -1753,7 +1753,7 @@ void svg_sendupdate(t_svg *x, t_canvas *c, t_symbol *s, } else { - sprintf(tag, "draw%lx.%lx", + sprintf(tag, "%s%lx.%lx", (in_array ? "scelem": "draw"), (long unsigned int)x->x_parent, (long unsigned int)data); } @@ -1927,7 +1927,7 @@ void svg_sendupdate(t_svg *x, t_canvas *c, t_symbol *s, else if (s == gensym("d")) { char tagbuf[MAXPDSTRING]; - sprintf(tagbuf, "draw%lx.%lx", + sprintf(tagbuf, "%s%lx.%lx", (in_array ? "scelem" : "draw"), (long unsigned int)parent, (long unsigned int)data); gui_start_vmess("gui_draw_configure", "xss", glist_getcanvas(c), tagbuf, "d"); @@ -4213,7 +4213,8 @@ static void draw_vis(t_gobj *z, t_glist *glist, t_glist *parentglist, one for this specific draw item */ char tagbuf[MAXPDSTRING]; - sprintf(tagbuf, "draw%lx.%lx", (long unsigned int)x, + sprintf(tagbuf, "%s%lx.%lx", in_array ? "scelem" : "draw", + (long unsigned int)x, (long unsigned int)data); gui_s(tagbuf); gui_end_array(); @@ -5424,7 +5425,7 @@ static void curve_setup(void) /* --------- plots for showing arrays --------------- */ -t_class *plot_class; +static t_class *plot_class; typedef struct _plot { @@ -5446,6 +5447,11 @@ typedef struct _plot t_fielddesc x_symfillcolor; /* fill color as hex symbol */ } t_plot; +int is_plot_class(t_gobj *y) +{ + return (pd_class(&y->g_pd) == plot_class); +} + static void *plot_new(t_symbol *classsym, t_int argc, t_atom *argv) { if (legacy_draw_in_group(canvas_getcurrent())) @@ -8287,8 +8293,6 @@ static void drawimage_vis(t_gobj *z, t_glist *glist, t_glist *parentglist, t_float xloc = fielddesc_getcoord(&svg->x_x.a_attr, template, data, 0); t_float yloc = fielddesc_getcoord(&svg->x_y.a_attr, template, data, 0); -fprintf(stderr, "xloc is %g\n", xloc); -fprintf(stderr, "yloc is %g\n", yloc); char tagbuf[MAXPDSTRING]; char parent_tagbuf[MAXPDSTRING]; sprintf(tagbuf, "draw%lx.%lx", @@ -8617,7 +8621,8 @@ void svg_parentwidgettogui(t_gobj *z, t_scalar *sc, t_glist *owner, if (pd_class(&z->g_pd) == draw_class) { t_draw *x = (t_draw *)z; - sprintf(tagbuf, "draw%lx.%lx", (long unsigned int)x, + sprintf(tagbuf, "%s%lx.%lx", (sc->sc_vec == data) ? "draw" : "scelem", + (long unsigned int)x, (long unsigned int)data); gui_start_vmess("gui_draw_configure_all", "xs", glist_getcanvas(owner), tagbuf); @@ -8627,7 +8632,8 @@ void svg_parentwidgettogui(t_gobj *z, t_scalar *sc, t_glist *owner, else if (pd_class(&z->g_pd) == drawimage_class) { t_drawimage *x = (t_drawimage *)z; - sprintf(tagbuf, "draw%lx.%lx", (long unsigned int)x, + sprintf(tagbuf, "%s%lx.%lx", (sc->sc_vec == data) ? "draw" : "scelem", + (long unsigned int)x, (long unsigned int)data); gui_start_vmess("gui_draw_configure_all", "xs", glist_getcanvas(owner), tagbuf); diff --git a/pd/src/g_traversal.c b/pd/src/g_traversal.c index ca3e69512..c1ecfd2f7 100644 --- a/pd/src/g_traversal.c +++ b/pd/src/g_traversal.c @@ -706,10 +706,12 @@ static void set_bang(t_set *x) else { t_array *owner_array = gs->gs_un.gs_array; - while (owner_array->a_gp.gp_stub->gs_which == GP_ARRAY) - owner_array = owner_array->a_gp.gp_stub->gs_un.gs_array; - scalar_redraw((t_scalar *)(owner_array->a_gp.gp_un.gp_gobj), - owner_array->a_gp.gp_stub->gs_un.gs_glist); + t_array *top_array = owner_array; + while (top_array->a_gp.gp_stub->gs_which == GP_ARRAY) + top_array = top_array->a_gp.gp_stub->gs_un.gs_array; + array_configure((t_scalar *)(top_array->a_gp.gp_un.gp_gobj), + top_array->a_gp.gp_stub->gs_un.gs_glist, owner_array, + vec); } } -- GitLab