From a25ef3dc475f873d928a0c253ae3e38986ebac7e Mon Sep 17 00:00:00 2001 From: Guillem <guillembartrina@gmail.com> Date: Mon, 24 Aug 2020 21:06:15 +0200 Subject: [PATCH] add [abdefs] object (methods: get, instances, del, clean) with an interactive dialog, add new element type for dialog_external --- pd/nw/dialog_external.html | 4 +- pd/src/g_canvas.c | 205 +++++++++++++++++++++++++++++++++++++ pd/src/g_canvas.h | 1 + pd/src/g_editor.c | 2 - 4 files changed, 209 insertions(+), 3 deletions(-) diff --git a/pd/nw/dialog_external.html b/pd/nw/dialog_external.html index 63b31d643..81fcaf5ee 100644 --- a/pd/nw/dialog_external.html +++ b/pd/nw/dialog_external.html @@ -94,7 +94,8 @@ function parse_attrs(attrs) { if (token.length > 1) { elem.type = token[token.length - 1]; if (elem.type !== "symbol" && - elem.type !== "toggle") { + elem.type !== "toggle" && + elem.type !== "hidden") { // no suffix defaults to "number" elem.type = "number"; } else { @@ -162,6 +163,7 @@ function get_input_type(t) { return t === "symbol" ? "text" : t === "number" ? "text" : t === "toggle" ? "checkbox": + t === "hidden" ? "hidden": "text"; } diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c index 9599ad394..d6d1ff5c6 100644 --- a/pd/src/g_canvas.c +++ b/pd/src/g_canvas.c @@ -2330,6 +2330,26 @@ static t_ab_definition *canvas_add_ab(t_canvas *x, t_symbol *name, t_binbuf *sou return (0); } +static int canvas_del_ab(t_canvas *x, t_symbol *name) +{ + t_canvas *c = canvas_getrootfor_ab(x); + t_ab_definition *abdef, *abdefpre; + for(abdef = c->gl_abdefs, abdefpre = 0; abdef; abdefpre = abdef, abdef = abdef->ad_next) + { + if(abdef->ad_name == name) + { + if(abdefpre) abdefpre->ad_next = abdef->ad_next; + else c->gl_abdefs = abdef->ad_next; + binbuf_free(abdef->ad_source); + freebytes(abdef->ad_dep, sizeof(t_ab_definition*)*abdef->ad_numdep); + freebytes(abdef->ad_deprefs, sizeof(int)*abdef->ad_numdep); + freebytes(abdef, sizeof(t_ab_definition)); + return (1); + } + } + return (0); +} + /* given the ab definitions list, returns its topological ordering */ static int currvisflag = 0; @@ -2513,6 +2533,181 @@ static void *ab_new(t_symbol *s, int argc, t_atom *argv) return (newest); } +/* --------- */ + +static t_class *abdefs_class; + +typedef struct _abdefs +{ + t_object x_obj; + t_canvas *x_canvas; + int x_od; +} t_abdefs; + +static void *abdefs_new(void) +{ + t_abdefs *x = (t_abdefs *)pd_new(abdefs_class); + x->x_canvas = canvas_getcurrent(); + x->x_od = 0; + outlet_new(&x->x_obj, &s_list); + return (x); +} + +static void abdefs_get(t_abdefs *x); +static void abdefs_bang(t_abdefs *x) +{ + abdefs_get(x); +} + +static void abdefs_get(t_abdefs *x) +{ + t_canvas *r = canvas_getrootfor_ab(x->x_canvas); + t_binbuf *out = binbuf_new(); + t_ab_definition *abdef; + for(abdef = r->gl_abdefs; abdef; abdef = abdef->ad_next) + { + binbuf_addv(out, "si;", abdef->ad_name, abdef->ad_numinstances); + } + outlet_list(x->x_obj.ob_outlet, &s_list, + binbuf_getnatom(out), binbuf_getvec(out)); + binbuf_free(out); +} + +static void abdefs_instances(t_abdefs *x, t_symbol *s) +{ + t_ab_definition *abdef; + if((abdef = canvas_find_ab(x->x_canvas, s))) + { + t_atom at[1]; + SETFLOAT(at, abdef->ad_numinstances); + outlet_list(x->x_obj.ob_outlet, &s_list, 1, at); + } + else + pd_error(x, "couldn't find definition for '%s'", s->s_name); +} + +static void abdefs_del(t_abdefs *x, t_symbol *s) +{ + t_ab_definition *abdef; + if((abdef = canvas_find_ab(x->x_canvas, s)) && !abdef->ad_numinstances) + { + canvas_del_ab(x->x_canvas, s); + post("abdefs: definition for '%s' has been deleted", s->s_name); + } + else if(abdef) + pd_error(x, "couldn't delete '%s', it has at least one instance", s->s_name); + else + pd_error(x, "couldn't find definition for '%s'", s->s_name); +} + +static void abdefs_clean(t_abdefs *x) +{ + t_canvas *c = canvas_getrootfor_ab(x->x_canvas); + t_ab_definition *abdef, *abdefpre; + int tot = 0; + for(abdef = c->gl_abdefs, abdefpre = 0; abdef; ) + { + if(!abdef->ad_numinstances) + { + if(abdefpre) abdefpre->ad_next = abdef->ad_next; + else c->gl_abdefs = abdef->ad_next; + binbuf_free(abdef->ad_source); + freebytes(abdef->ad_dep, sizeof(t_ab_definition*)*abdef->ad_numdep); + freebytes(abdef->ad_deprefs, sizeof(int)*abdef->ad_numdep); + freebytes(abdef, sizeof(t_ab_definition)); + if(abdefpre) abdef = abdefpre->ad_next; + else abdef = c->gl_abdefs; + tot++; + } + else + { + abdefpre = abdef; + abdef = abdef->ad_next; + } + } + post("abdefs: a total of '%d' ab definitions with zero instances have been deleted", tot); +} + +static void abdefs_menuopen(t_abdefs *x) +{ + if(x->x_od) + { + pd_error(x, "the dialog is already open"); + return; + } + x->x_od = 1; + + char buf[MAXPDSTRING]; + t_canvas *c = canvas_getrootfor_ab(x->x_canvas); + t_ab_definition *abdef; + char *gfx_tag = gfxstub_new2(&x->x_obj.ob_pd, x); + gui_start_vmess("gui_external_dialog", "s", gfx_tag); + gui_s("[ab] definitions"); + gui_start_array(); + gui_s("select the definitions you want to delete_hidden"); gui_i(0); + gui_s("name | #instances_hidden"); gui_i(0); + gui_s("----------------------_hidden"); gui_i(0); + for(abdef = c->gl_abdefs; abdef; abdef = abdef->ad_next) + { + sprintf(buf, "%s | %d_toggle", abdef->ad_name->s_name, abdef->ad_numinstances); + gui_s(buf); gui_i(0); + } + gui_end_array(); + gui_end_vmess(); +} + +static void abdefs_dialog(t_abdefs *x, t_symbol *s, int argc, t_atom *argv) +{ + if(!x->x_od) + { + pd_error(x, "deletion already performed, reopen the dialog if you want to delete more definitions"); + return; + } + + argc -= 3; + argv += 3; + + t_canvas *c = canvas_getrootfor_ab(x->x_canvas); + t_ab_definition *abdef, *abdefpre; + int tot = 0, del = 0; + for(abdef = c->gl_abdefs, abdefpre = 0; abdef; ) + { + if(atom_getfloat(argv)) + { + if(!abdef->ad_numinstances) + { + if(abdefpre) abdefpre->ad_next = abdef->ad_next; + else c->gl_abdefs = abdef->ad_next; + binbuf_free(abdef->ad_source); + freebytes(abdef->ad_dep, sizeof(t_ab_definition*)*abdef->ad_numdep); + freebytes(abdef->ad_deprefs, sizeof(int)*abdef->ad_numdep); + freebytes(abdef, sizeof(t_ab_definition)); + if(abdefpre) abdef = abdefpre->ad_next; + else abdef = c->gl_abdefs; + del++; + } + else + { + pd_error(x, "couldn't delete '%s', it has at least one instance", + abdef->ad_name->s_name); + abdefpre = abdef; + abdef = abdef->ad_next; + } + tot++; + } + else + { + abdefpre = abdef; + abdef = abdef->ad_next; + } + argv++; + } + + x->x_od = 0; + if(tot) + post("abdefs: a total of '%d' ab definitions with zero instances have been deleted", del); +} + /* ------------------------------- declare ------------------------ */ /* put "declare" objects in a patch to tell it about the environment in @@ -3361,6 +3556,16 @@ void g_canvas_setup(void) class_addmethod(canvas_class, (t_method)canvas_abframe, gensym("abframe"), A_FLOAT, 0); + abdefs_class = class_new(gensym("abdefs"), (t_newmethod)abdefs_new, + 0, sizeof(t_abdefs), CLASS_DEFAULT, A_NULL); + class_addbang(abdefs_class, (t_method)abdefs_bang); + class_addmethod(abdefs_class, (t_method)abdefs_get, gensym("get"), 0); + class_addmethod(abdefs_class, (t_method)abdefs_instances, gensym("instances"), A_SYMBOL, 0); + class_addmethod(abdefs_class, (t_method)abdefs_del, gensym("del"), A_SYMBOL, 0); + class_addmethod(abdefs_class, (t_method)abdefs_clean, gensym("clean"), 0); + class_addmethod(abdefs_class, (t_method)abdefs_menuopen, gensym("menu-open"), 0); + class_addmethod(abdefs_class, (t_method)abdefs_dialog, gensym("dialog"), A_GIMME, 0); + /*---------------------------- declare ------------------- */ declare_class = class_new(gensym("declare"), (t_newmethod)declare_new, (t_method)declare_free, sizeof(t_declare), CLASS_NOINLET, A_GIMME, 0); diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h index 26c492e5f..2be170b3d 100644 --- a/pd/src/g_canvas.h +++ b/pd/src/g_canvas.h @@ -576,6 +576,7 @@ EXTERN void canvas_setcurrent(t_canvas *x); EXTERN void canvas_unsetcurrent(t_canvas *x); EXTERN t_symbol *canvas_realizedollar(t_canvas *x, t_symbol *s); EXTERN t_canvas *canvas_getrootfor(t_canvas *x); +EXTERN t_canvas *canvas_getrootfor_ab(t_canvas *x); EXTERN void canvas_dirty(t_canvas *x, t_floatarg n); EXTERN int canvas_getfont(t_canvas *x); typedef int (*t_canvasapply)(t_canvas *x, t_int x1, t_int x2, t_int x3); diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c index 29feb81d1..53cadb650 100644 --- a/pd/src/g_editor.c +++ b/pd/src/g_editor.c @@ -1508,8 +1508,6 @@ static void glist_doreload_ab_packed(t_canvas *x, t_reload_ab_data *data) glist_doreload_ab(x, data->a, data->e); } -t_canvas *canvas_getrootfor_ab(t_canvas *x); - /* reload ab instances */ void canvas_reload_ab(t_canvas *x) { -- GitLab