diff --git a/pd/doc/5.reference/preset_hub-help.pd b/pd/doc/5.reference/preset_hub-help.pd index fae1643c9245f77c3f5e9d7e15ffd78376c72947..d70ee678bf3ca1aa7bec0c991d49b387a33cfc91 100644 --- a/pd/doc/5.reference/preset_hub-help.pd +++ b/pd/doc/5.reference/preset_hub-help.pd @@ -227,7 +227,7 @@ same scope \, they will see each other regardless of what scope is given them at creation time \, including no scope at all (as is the case with the rest of pd-l2ork \, \$1 with no argument given reverts to 0).; -#N canvas 186 348 428 332 More_info 0; +#N canvas 186 348 429 332 More_info 0; #X obj 1 1 cnv 15 425 20 empty \$0-pddp.cnv.subheading empty 3 12 0 14 -204280 -1 0; #X text 7 1 [preset_hub] More info on modular scope; @@ -241,13 +241,13 @@ to 0).; #X floatatom 38 157 5 0 0 0 - - -, f 5; #X text 142 39 <-- recall presets 0-5; #X text 73 155 <-- note how the value changes with each recall; -#X text 34 191 Notice how the hub and node are paired even no optional -argument has been given to this patch?Note that in this case [preset_hub -\$1] is different from [preset_hub] as latter actually is defined as -null symbol or "" while former is equal to float 0 (if no argument -is given. This hub-node pairing is also independent from anything found -in parent patch since node has found its match in this patcher before -looking one level up.; +#X text 34 191 Notice how the hub and node are paired even though no +optional argument has been given to this patch?Note that in this +case [preset_hub \$1] is different from [preset_hub] as latter actually +is defined as null symbol or "" while former is equal to float 0 (if +no argument is given). This hub-node pairing is also independent from +anything found in parent patch since node has found its match in this +patcher before looking one level up.; #X connect 3 0 2 0; #X connect 4 0 2 0; #X connect 5 0 3 0; diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c index c20fee498daa24ea5fc5e323fa415c51305c3379..c294e0287079bd4392d03994c59fdacc918ffb08 100644 --- a/pd/src/g_editor.c +++ b/pd/src/g_editor.c @@ -1425,6 +1425,7 @@ typedef struct _undo_apply void *canvas_undo_set_apply(t_canvas *x, int n) { + //fprintf(stderr,"canvas_undo_set_apply\n"); t_undo_apply *buf; t_gobj *obj; t_linetraverser t; @@ -1433,6 +1434,13 @@ void *canvas_undo_set_apply(t_canvas *x, int n) we are working on */ if (!x->gl_edit) canvas_editmode(x, 1); + + // deselect all objects (if we are editing one while multiple are + // selected, upon undoing this will recreate other selected objects, + // effectively resulting in unwanted duplicates) + // LATER: consider allowing concurrent editing of multiple objects + glist_noselect(x); + obj = glist_nth(x, n); if (obj && !glist_isselected(x, obj)) glist_select(x, obj); @@ -1470,6 +1478,7 @@ void *canvas_undo_set_apply(t_canvas *x, int n) void canvas_undo_apply(t_canvas *x, void *z, int action) { + //fprintf(stderr,"canvas_undo_apply\n"); t_undo_apply *buf = z; if (action == UNDO_UNDO || action == UNDO_REDO) { @@ -6376,11 +6385,17 @@ void canvas_connect(t_canvas *x, t_floatarg fwhoout, t_floatarg foutno, /* if object creation failed, make dummy inlets or outlets as needed */ if (pd_class(&src->g_pd) == text_class && objsrc->te_type == T_OBJECT) + { while (outno >= obj_noutlets(objsrc)) outlet_new(objsrc, 0); + //fprintf(stderr,"canvas_connect got fake outlets\n"); + } if (pd_class(&sink->g_pd) == text_class && objsink->te_type == T_OBJECT) + { while (inno >= obj_ninlets(objsink)) inlet_new(objsink, &objsink->ob_pd, 0, 0); + //fprintf(stderr,"canvas_connect got fake inlets\n"); + } if (!canvas_isconnected(x, objsrc, outno, objsink, inno)) { diff --git a/pd/src/g_text.c b/pd/src/g_text.c index bfaf69551283c049135508ac94565e2ce1d00817..81ff821d98105ccd3314358b78840daa235839c8 100644 --- a/pd/src/g_text.c +++ b/pd/src/g_text.c @@ -181,8 +181,8 @@ static void canvas_objtext(t_glist *gl, int xpix, int ypix, if (!x) { /* LATER make the color reflect this */ - //fprintf(stderr,"creating blank object\n"); x = (t_text *)pd_new(text_class); + //fprintf(stderr,"creating blank object %lx\n", x); } /* special case: an object, like preset_hub, hides its arguments beyond the first n, so we modify its binbuf here */ @@ -1407,6 +1407,15 @@ static void text_getrect(t_gobj *z, t_glist *glist, int no = obj_noutlets(ob); int ni = obj_ninlets(ob); + /* + // debug chunk + char *bufdbg; + int bufsizedbg; + if (y) rtext_gettext(y, &bufdbg, &bufsizedbg); + if (!strncmp(bufdbg, "gate", 4) || strlen(bufdbg) == 0) + fprintf(stderr,"text_getrect nlets %d %d <%s>\n", ni, no, ( y ? bufdbg : "null" )); + */ + int m = ( ni > no ? ni : no); //let's see if the object has more nlets than //its text width and resize them accordingly @@ -1592,7 +1601,7 @@ static void text_select(t_gobj *z, t_glist *glist, int state) glist_getcanvas(glist), rtext_gettag(y)); if (pd_class(&x->te_pd) == text_class && x->te_type != T_TEXT) - sys_vgui(".x%lx.c itemconfigure %sR -strokewidth 2 -strokedasharray {2 3} " + sys_vgui(".x%lx.c itemconfigure %sR -strokewidth 2 -strokelinecap projecting -strokedasharray {2 3} " "-fill %s\n", glist_getcanvas(glist), rtext_gettag(y), invalid_fill); @@ -1996,6 +2005,8 @@ void glist_drawiofor_withtag(t_glist *glist, t_object *ob, int firsttime, void text_drawborder(t_text *x, t_glist *glist, char *tag, int width2, int height2, int firsttime) { + //fprintf(stderr,"text_drawborder\n"); + t_object *ob; int x1, y1, x2, y2; @@ -2157,7 +2168,7 @@ void text_drawborder_withtag(t_text *x, t_glist *glist, if (pd_class(&x->te_pd) == text_class) { pattern = "-"; - outline = "$pd_colors(dash_outline) -strokewidth 2"; + outline = "$pd_colors(dash_outline) -strokewidth 2 -strokelinecap projecting -strokedasharray {2 3}"; fill = invalid_fill; } else @@ -2205,7 +2216,7 @@ void text_drawborder_withtag(t_text *x, t_glist *glist, x2, y2, x1, y2, x1, y1, tag, tag); } - /* for comments, just draw a bar on RHS if unlocked; when a visible + /* for comments, draw a dotted box; when a visible canvas is unlocked we have to call this anew on all comments, and when locked we erase them all via the annoying "commentbar" tag. */ else if (x->te_type == T_TEXT && glist->gl_edit) @@ -2277,6 +2288,23 @@ static int compare_subpatch_selectors(t_atom *a, t_atom *b) return 0; } +void text_checkvalidwidth(t_glist *glist) +{ + // readjust border in case the new object is invalid and it has more connections + // than what the default width allows (this typically happens when there is a valid + // object that has been replaced by an invalid one and during recreation the new + // object has 0 inlets and outlets and is therefore unaware of its possibly greater + // width) + t_gobj *yg = glist->gl_list; + while (yg->g_next) + yg = yg->g_next; + t_text *newest_t = (t_text *)yg; + //fprintf(stderr, "newest object text class is %lx\n", newest_t); + t_rtext *yn = glist_findrtext(glist, newest_t); + if (yn && pd_class(&newest_t->te_pd) == text_class && newest_t->te_type != T_TEXT) + text_drawborder(newest_t, glist, rtext_gettag(yn), rtext_width(yn), rtext_height(yn), 0); +} + /* change text; if T_OBJECT, remake it. */ void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize, int pos) @@ -2354,6 +2382,7 @@ void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize, int pos) canvas_restoreconnections(glist_getcanvas(glist)); //canvas_apply_restore_original_position(glist_getcanvas(glist), // pos); + text_checkvalidwidth(glist); } else { diff --git a/pd/src/g_undo.c b/pd/src/g_undo.c index 6356b7841140be164d23cdb98f18fb70b4c799ea..b0fb5b7126ecfd043625012ea5b2327620915c45 100644 --- a/pd/src/g_undo.c +++ b/pd/src/g_undo.c @@ -10,6 +10,8 @@ int we_are_undoing = 0; extern const char *canvas_undo_name; extern void glob_preset_node_list_seek_hub(void); +extern void glob_preset_node_list_check_loc_and_update(void); +extern void text_checkvalidwidth(t_glist *glist); t_undo_action *canvas_undo_init(t_canvas *x) { @@ -94,6 +96,7 @@ void canvas_undo_undo(t_canvas *x) { sys_vgui("pdtk_undomenu .x%lx %s %s\n", x, undo_action, redo_action); + text_checkvalidwidth(x); canvas_getscroll(x); } canvas_dirty(x, 1); @@ -139,6 +142,7 @@ void canvas_undo_redo(t_canvas *x) { sys_vgui("pdtk_undomenu .x%lx %s %s\n", x, undo_action, redo_action); + text_checkvalidwidth(x); canvas_getscroll(x); } canvas_dirty(x, 1); diff --git a/pd/src/x_connective.c b/pd/src/x_connective.c index 3c7e328583a483d818abf504c0bdf3213ad5d304..5e7ec6b3d3a1b24d2aa92aec0dacbb36d2ca8e09 100644 --- a/pd/src/x_connective.c +++ b/pd/src/x_connective.c @@ -1142,7 +1142,7 @@ static void trigger_list(t_trigger *x, t_symbol *s, int argc, t_atom *argv) outlet_bang(u->u_outlet); else if (u->u_type == TR_SYMBOL) outlet_symbol(u->u_outlet, - (argc ? atom_getsymbol(argv) : &s_symbol)); + (argc ? atom_getsymbol(argv) : (s != NULL ? s : &s_symbol))); else if (u->u_type == TR_ANYTHING) outlet_anything(u->u_outlet, s, argc, argv); else if (u->u_type == TR_POINTER) @@ -1165,9 +1165,10 @@ static void trigger_list(t_trigger *x, t_symbol *s, int argc, t_atom *argv) static void trigger_anything(t_trigger *x, t_symbol *s, int argc, t_atom *argv) { - //fprintf(stderr,"trigger_anything %s\n", s->s_name); + //fprintf(stderr,"trigger_anything %s %d\n", s->s_name, argc); + t_atom *av2 = NULL; t_triggerout *u; - int i; + int i, j = 0; for (i = x->x_n, u = x->x_vec + i; u--, i--;) { if (u->u_type == TR_BANG) @@ -1185,7 +1186,70 @@ static void trigger_anything(t_trigger *x, t_symbol *s, int argc, t_atom *argv) { outlet_symbol(u->u_outlet, &u->u_sym); } - else trigger_symbol(x, s); + //else trigger_symbol(x, s); + else + { + // copying trigger_list behavior except that here we keep + // the outlet number and therefore avoid redundant printouts + if (u->u_type == TR_FLOAT) + { + //fprintf(stderr,"trigger_anything -> TR_FLOAT %d\n", argc); + outlet_float(u->u_outlet, (argc ? atom_getfloat(argv) : 0)); + } + else if (u->u_type == TR_BANG) + { + //fprintf(stderr,"trigger_anything -> TR_BANG %d\n", argc); + outlet_bang(u->u_outlet); + } + else if (u->u_type == TR_SYMBOL) + { + //fprintf(stderr,"trigger_anything -> TR_SYMBOL %d\n", argc); + outlet_symbol(u->u_outlet, + (s != NULL ? s : (argc ? atom_getsymbol(argv) : &s_symbol))); + } + else if (u->u_type == TR_ANYTHING) + { + //fprintf(stderr,"trigger_anything -> TR_ANYTHING %d\n", argc); + outlet_anything(u->u_outlet, s, argc, argv); + } + else if (u->u_type == TR_POINTER) + { + //fprintf(stderr,"trigger_anything -> TR_POINTER %d\n", argc); + if (!argc || argv->a_type != TR_POINTER) + pd_error(x, "unpack: bad pointer"); + else outlet_pointer(u->u_outlet, argv->a_w.w_gpointer); + } + else if (u->u_type == TR_STATIC_FLOAT) + { + //fprintf(stderr,"trigger_anything -> TR_STATIC_FLOAT %d\n", argc); + outlet_float(u->u_outlet, u->u_float); + } + else if (u->u_type == TR_STATIC_SYMBOL) + { + //fprintf(stderr,"trigger_anything -> TR_STATIC_SYMBOL %d\n", argc); + outlet_symbol(u->u_outlet, &u->u_sym); + } + else + { + // Ico: don't have to worry about zero element case (AFAICT) + av2 = (t_atom *)getbytes((argc + 1) * sizeof(t_atom)); + SETSYMBOL(av2, s); + if (argc == 0) + { + //fprintf(stderr,"trigger_anything -> symbol %d\n", argc); + outlet_list(u->u_outlet, &s_symbol, argc+1, av2); + } + else + { + for (j = 0; j < argc; j++) + av2[j + 1] = argv[j]; + //fprintf(stderr,"trigger_anything -> list %d\n", argc); + SETSYMBOL(av2, s); + outlet_list(u->u_outlet, &s_list, argc+1, av2); + } + freebytes(av2, (argc + 1) * sizeof(t_atom)); + } + } } }