diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c index dd92ecc0398026cb73304096a9f56d4ace92295f..d86b4bba66cd529d4ed80b8a13d22379fccb2efe 100644 --- a/pd/src/g_canvas.c +++ b/pd/src/g_canvas.c @@ -1778,6 +1778,31 @@ int canvas_open(t_canvas *x, const char *name, const char *ext, return(result); } +static void canvas_f(t_canvas *x, t_symbol *s, int argc, t_atom *argv) +{ + static int warned; + t_gobj *g, *g2; + t_object *ob; + if (argc > 1 && !warned) + { + post("** ignoring width or font settings from future Pd version **"); + warned = 1; + } + if (!x->gl_list) + return; + for (g = x->gl_list; g2 = g->g_next; g = g2) + ; + if (ob = pd_checkobject(&g->g_pd)) + { + ob->te_width = atom_getfloatarg(0, argc, argv); + if (glist_isvisible(x)) + { + gobj_vis(g, x, 0); + gobj_vis(g, x, 1); + } + } +} + void canvasgop_draw_move(t_canvas *x, int doit) { //delete the earlier GOP window so that when dragging @@ -2131,6 +2156,9 @@ void g_canvas_setup(void) class_addmethod(canvas_class, (t_method)canvas_declare, gensym("declare"), A_GIMME, 0); +/*--------------- future message to set formatting -------------- */ + class_addmethod(canvas_class, (t_method)canvas_f, + gensym("f"), A_GIMME, 0); /* -------------- setups from other files for canvas_class ---------------- */ g_graph_setup(); g_editor_setup(); diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h index 47781baac80bc3ff0ae97c99b92cbdaa3c76ba96..8c442374f5e05e0c2c641228ae17c3f567669760 100644 --- a/pd/src/g_canvas.h +++ b/pd/src/g_canvas.h @@ -124,6 +124,9 @@ typedef struct _editor t_magicGlass *gl_magic_glass; /* magic glass object */ char canvas_cnct_inlet_tag[4096]; /* tags for currently highlighted nlets */ char canvas_cnct_outlet_tag[4096]; + t_clock *e_clock; /* clock to filter GUI move messages */ + int e_xnew; /* xpos for next move event */ + int e_ynew; /* ypos, similarly */ } t_editor; #define MA_NONE 0 /* e_onmotion: do nothing on mouse motion */ @@ -132,6 +135,7 @@ typedef struct _editor #define MA_REGION 3 /* selection region */ #define MA_PASSOUT 4 /* send on to e_grab */ #define MA_DRAGTEXT 5 /* drag in text editor to alter selection */ +#define MA_RESIZE 6 /* drag to resize */ /* editor structure for "garrays". We don't bother to delete and regenerate this structure when the "garray" becomes invisible or visible, although we @@ -384,6 +388,8 @@ struct _parentwidgetbehavior #define CURSOR_EDITMODE_NOTHING 4 #define CURSOR_EDITMODE_CONNECT 5 #define CURSOR_EDITMODE_DISCONNECT 6 +#define CURSOR_EDITMODE_RESIZE 7 +#define CURSOR_EDITMODE_RESIZE_BOTTOM_RIGHT 8 EXTERN void canvas_setcursor(t_glist *x, unsigned int cursornum); extern t_canvas *canvas_editing; /* last canvas to start text edting */ diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c index 0728564ba7ee4fc13db040b1b9c4fad52c901f26..ce3d0ab94bc86d87836d86ce14ba247c54a69b02 100644 --- a/pd/src/g_editor.c +++ b/pd/src/g_editor.c @@ -1966,7 +1966,9 @@ static char *cursorlist[] = { "$cursor_runmode_addpoint", "$cursor_editmode_nothing", "$cursor_editmode_connect", - "$cursor_editmode_disconnect" + "$cursor_editmode_disconnect", + "$cursor_editmode_resize", + "$cursor_editmode_resize_bottom_right" }; void canvas_setcursor(t_canvas *x, unsigned int cursornum) @@ -2835,8 +2837,36 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which, /* look for an outlet we just clicked onto */ int noutlet; int ninlet; - // if object is valid, has outlets, and we are within the bottom area of an object - if (ob && (noutlet = obj_noutlets(ob)) && ypos >= y2-4) + /* resize? only for "true" text boxes or canvases*/ + if (!sys_k12_mode && ob && !x->gl_editor->e_textedfor && + (ob->te_pd->c_wb == &text_widgetbehavior || + ob->ob_pd == canvas_class) && + xpos >= x2-4 && ypos < y2-4) + { + if (doit) + { + if (!glist_isselected(x, y)) + { + glist_noselect(x); + glist_select(x, y); + } + x->gl_editor->e_onmotion = MA_RESIZE; + x->gl_editor->e_xwas = x1; + x->gl_editor->e_ywas = y1; + x->gl_editor->e_xnew = xpos; + x->gl_editor->e_ynew = ypos; + canvas_undo_add(x, 6, "resize", canvas_undo_set_apply(x, glist_getindex(x, y))); + } + else { + if (ob->ob_pd != canvas_class || !((t_canvas *)ob)->gl_isgraph) + canvas_setcursor(x, CURSOR_EDITMODE_RESIZE); + else canvas_setcursor(x, CURSOR_EDITMODE_RESIZE_BOTTOM_RIGHT); + canvas_check_nlet_highlights(x); + } + } + /* look for an outlet */ + // if object is valid, has outlets, and we are within the bottom area of an object + else if (ob && (noutlet = obj_noutlets(ob)) && ypos >= y2-4) { int width = x2 - x1; int nout1 = (noutlet > 1 ? noutlet - 1 : 1); @@ -3990,9 +4020,11 @@ void canvas_mouseup(t_canvas *x, canvas_doconnect(x, xpos, ypos, which, 1); else if (x->gl_editor->e_onmotion == MA_REGION) canvas_doregion(x, xpos, ypos, 1); - else if (x->gl_editor->e_onmotion == MA_MOVE) + else if (x->gl_editor->e_onmotion == MA_MOVE || + x->gl_editor->e_onmotion == MA_RESIZE) { - /* after motion, if there's only one item selected, activate it */ + /* after motion or resizing, if there's only one text item + selected, activate the text */ if (x->gl_editor->e_selection && !(x->gl_editor->e_selection->sel_next)) { @@ -4330,6 +4362,8 @@ void canvas_motion(t_canvas *x, t_floatarg xpos, t_floatarg ypos, xpos - x->gl_editor->e_xwas, ypos - x->gl_editor->e_ywas); x->gl_editor->e_xwas = xpos; x->gl_editor->e_ywas = ypos; + x->gl_editor->e_xnew = xpos; + x->gl_editor->e_ynew = ypos; //sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", x); //sys_vgui("pdtk_check_scroll_on_motion .x%lx.c 20\n", x); } @@ -4358,6 +4392,44 @@ void canvas_motion(t_canvas *x, t_floatarg xpos, t_floatarg ypos, rtext_mouse(rt, xpos - x->gl_editor->e_xwas, ypos - x->gl_editor->e_ywas, RTEXT_DRAG); } + else if (x->gl_editor->e_onmotion == MA_RESIZE) + { + int x11=0, y11=0, x12=0, y12=0; + t_gobj *y1; + if (y1 = canvas_findhitbox(x, + x->gl_editor->e_xwas, x->gl_editor->e_ywas, + &x11, &y11, &x12, &y12)) + { + int wantwidth = xpos - x11; + t_gotfn sizefn; + t_object *ob = pd_checkobject(&y1->g_pd); + if (ob && ob->te_pd->c_wb == &text_widgetbehavior || + (ob->ob_pd == canvas_class && + !((t_canvas *)ob)->gl_isgraph)) + { + wantwidth = wantwidth / sys_fontwidth(glist_getfont(x)); + if (wantwidth < 1) + wantwidth = 1; + ob->te_width = wantwidth; + gobj_vis(y1, x, 0); + canvas_fixlinesfor(x, ob); + gobj_vis(y1, x, 1); + canvas_dirty(x, 1); + } + else if (ob && ob->ob_pd == canvas_class) + { + gobj_vis(y1, x, 0); + ((t_canvas *)ob)->gl_pixwidth += xpos - x->gl_editor->e_xnew; + ((t_canvas *)ob)->gl_pixheight += ypos - x->gl_editor->e_ynew; + x->gl_editor->e_xnew = xpos; + x->gl_editor->e_ynew = ypos; + canvas_fixlinesfor(x, ob); + gobj_vis(y1, x, 1); + canvas_dirty(x, 1); + } + else post("not resizable"); + } + } else canvas_doclick(x, xpos, ypos, 0, mod, 0); //if (toggle_moving == 1) { // sys_vgui("pdtk_update_xy_tooltip .x%lx %d %d\n", x, (int)xpos, (int)ypos); diff --git a/pd/src/g_graph.c b/pd/src/g_graph.c index a29c3f33a71bbcfc3ce80593e9075ff3e7ea8660..4134ce4138e8b09450aa0a7636048cd38978c620 100644 --- a/pd/src/g_graph.c +++ b/pd/src/g_graph.c @@ -1005,24 +1005,35 @@ void graph_checkgop_rect(t_gobj *z, t_glist *glist, //fprintf(stderr,"graph_checkgop_rect\n"); t_glist *x = (t_glist *)z; - int x21, y21, x22, y22; - text_widgetbehavior.w_getrectfn(z, glist, &x21, &y21, &x22, &y22); - if (x22 > *xp2) - *xp2 = x22; - if (y22 > *yp2) - *yp2 = y22; - int fw = sys_fontwidth(x->gl_font); - int fh = sys_fontheight(x->gl_font); - // WARNING: ugly hack trying to replicate rtext_senditup if we have no parent - // later consider fixing hardwired values - int tcols = strlen(x->gl_name->s_name) - 3; - int th = fh + fh * (tcols/60) + 4; - if (tcols > 60) tcols = 60; - int tw = fw * tcols + 4; - if (tw + *xp1 > *xp2) - *xp2 = tw + *xp1; - if (th + *yp1 > *yp2) - *yp2 = th + *yp1; + if (!x->gl_hidetext) { + int x21, y21, x22, y22; + text_widgetbehavior.w_getrectfn(z, glist, &x21, &y21, &x22, &y22); + if (x22 > *xp2) + *xp2 = x22; + if (y22 > *yp2) + *yp2 = y22; + int fw = sys_fontwidth(x->gl_font); + int fh = sys_fontheight(x->gl_font); + // WARNING: ugly hack trying to replicate rtext_senditup if we have no parent + // later consider fixing hardwired values + int tcols = strlen(x->gl_name->s_name) - 3; + int th = fh + fh * (tcols/60) + 4; + if (tcols > 60) tcols = 60; + int tw = fw * tcols + 4; + if (tw + *xp1 > *xp2) + *xp2 = tw + *xp1; + if (th + *yp1 > *yp2) + *yp2 = th + *yp1; + } else { + // failsafe where we cannot have a gop that is smaller than 1x1 pixels + // when the text is hidden + int in = obj_ninlets(pd_checkobject(&z->g_pd)) * IOWIDTH; + int out = obj_noutlets(pd_checkobject(&z->g_pd)) * IOWIDTH; + int minhsize = (in >= out ? in : out); + int minvsize = ((in > 0 ? 1 : 0) + (out > 0 ? 1 : 0)) * 2 + 6; + if (*xp2 < *xp1+minhsize) *xp2 = *xp1+minhsize; + if (*yp2 < *yp1+minvsize) *yp2 = *yp1+minvsize; + } } /* get the rectangle, enlarged to contain all the "contents" -- @@ -1080,9 +1091,7 @@ static void graph_getrect(t_gobj *z, t_glist *glist, //fprintf(stderr,"%d %d %d %d\n", x1, y1, x2, y2); // check if the text is not hidden and if so use that as the limit of the gop's size - if (!x->gl_hidetext) { - graph_checkgop_rect(z, glist, &x1, &y1, &x2, &y2); - } + graph_checkgop_rect(z, glist, &x1, &y1, &x2, &y2); /* fix visibility of edge items for garrays */ int has_garray = 0; diff --git a/pd/src/g_rtext.c b/pd/src/g_rtext.c index ebde12b90ee7b60c61e49f0269616369287831dc..9a8a443f38bd81232f2b0b18821f916bd7e82292 100644 --- a/pd/src/g_rtext.c +++ b/pd/src/g_rtext.c @@ -166,7 +166,7 @@ static int lastone(char *s, int c, int n) SEND_FIRST - draw the box for the first time SEND_UPDATE - redraw the updated box otherwise - don't draw, just calculate. - Called with *widthp and *heightpas coordinates of + Called with *widthp and *heightp as coordinates of a test point, the routine reports the index of the character found there in *indexp. *widthp and *heightp are set to the width and height of the entire text in pixels. @@ -196,7 +196,7 @@ extern int sys_oldtclversion; static void rtext_senditup(t_rtext *x, int action, int *widthp, int *heightp, int *indexp) { - //fprintf(stderr,"rtext_senditup %d %d\n", *widthp, *heightp); + //fprintf(stderr,"rtext_senditup <%s>\n", x->x_buf); if (x) { t_float dispx, dispy; char smallbuf[200], *tempbuf; @@ -204,9 +204,9 @@ static void rtext_senditup(t_rtext *x, int action, int *widthp, int *heightp, pixwide, pixhigh, font, fontwidth, fontheight, findx, findy; int reportedindex = 0; t_canvas *canvas = glist_getcanvas(x->x_glist); - int widthspec_c = x->x_text->te_width; // width if any specified int widthlimit_c = (widthspec_c ? widthspec_c : BOXWIDTH); // width limit in chars + //fprintf(stderr,"senditup widthlimit_c %d %d\n", widthspec_c, widthlimit_c); int inindex_b = 0; // index location in the buffer int inindex_c = 0; // index location in the u8 chars int selstart_b = 0, selend_b = 0; // selection start and end @@ -233,18 +233,20 @@ static void rtext_senditup(t_rtext *x, int action, int *widthp, int *heightp, int maxindex_b = u8_offset(x->x_buf + inindex_b, maxindex_c); int eatchar = 1; int foundit_b = firstone(x->x_buf + inindex_b, '\n', maxindex_b); - + int foundit_c; //following deals with \v replacement for \n in multiline comments int foundit_bv = firstone(x->x_buf + inindex_b, '\v', maxindex_b); //fprintf(stderr,"%d %d <%s>\n", foundit_b, foundit_bv, x->x_buf); if ((foundit_bv < foundit_b && foundit_bv != -1) || (foundit_b == -1 && foundit_bv != -1)) foundit_b = foundit_bv; - - int foundit_c; if (foundit_b < 0) //if we did not find an \n { + /* too much text to fit in one line? */ if (inchars_c > widthlimit_c) { - foundit_b = lastone(x->x_buf + inindex_b, ' ', maxindex_b); + /* is there a space to break the line at? OK if it's even + one byte past the end since in this context we know there's + more text */ + foundit_b = lastone(x->x_buf + inindex_b, ' ', maxindex_b + 1); if (foundit_b < 0) { foundit_b = maxindex_b; @@ -295,7 +297,7 @@ static void rtext_senditup(t_rtext *x, int action, int *widthp, int *heightp, if (nlines < 1) nlines = 1; if (!widthspec_c) { - while (ncolumns < 3) + while (ncolumns < (x->x_text->te_type == T_TEXT ? 1 : 3)) { tempbuf[outchars_b++] = ' '; ncolumns++; @@ -305,6 +307,21 @@ static void rtext_senditup(t_rtext *x, int action, int *widthp, int *heightp, pixwide = ncolumns * fontwidth + (LMARGIN + RMARGIN); pixhigh = nlines * fontheight + (TMARGIN + BMARGIN); + if (action && x->x_text->te_width && x->x_text->te_type != T_ATOM) + { + /* if our width is specified but the "natural" width is the + same as the specified width, set specified width to zero + so future text editing will automatically change width. + Except atoms whose content changes at runtime. */ + int widthwas = x->x_text->te_width, newwidth = 0, newheight = 0, + newindex = 0; + x->x_text->te_width = 0; + rtext_senditup(x, 0, &newwidth, &newheight, &newindex); + if (newwidth/fontwidth != widthwas) + x->x_text->te_width = widthwas; + else x->x_text->te_width = 0; + //fprintf(stderr,"senditup width %d %d %d\n", newwidth/fontwidth, widthwas, x->x_text->te_width); + } if (action == SEND_FIRST) { //fprintf(stderr,"canvas=.x%lx %s\n", (t_int)canvas, tempbuf); sys_vgui("pdtk_text_new .x%lx.c {%s %s text} %f %f {%.*s} %d %s\n", diff --git a/pd/src/g_text.c b/pd/src/g_text.c index e68258deb5207c1b4032266465e9e3893aa5fe56..aa4879748479b8ea280f820e9abed4cc5e783569 100644 --- a/pd/src/g_text.c +++ b/pd/src/g_text.c @@ -625,7 +625,16 @@ static void message_free(t_message *x) void canvas_msg(t_glist *gl, t_symbol *s, int argc, t_atom *argv) { - //fprintf(stderr,"canvas_msg\n"); + /*fprintf(stderr,"canvas_msg\n"); + int i = 0; + while(i < argc) { + if (argv[i].a_type == A_FLOAT) + fprintf(stderr," %f", atom_getfloatarg(i, argc, argv)); + else + fprintf(stderr," %s", atom_getsymbolarg(i, argc, argv)->s_name); + i++; + } + fprintf(stderr,"\n");*/ t_message *x = (t_message *)pd_new(message_class); x->m_messresponder.mr_pd = messresponder_class; x->m_messresponder.mr_outlet = outlet_new(&x->m_text, &s_float); @@ -1240,6 +1249,7 @@ static void text_getrect(t_gobj *z, t_glist *glist, { t_rtext *y = glist_findrtext(glist, x); width = rtext_width(y); + height = rtext_height(y) - (iscomment << 1); //fprintf(stderr,"rtext_width=%d\n", width); @@ -1555,7 +1565,6 @@ void text_save(t_gobj *z, t_binbuf *b) //fprintf(stderr, "this must be it\n"); binbuf_addbinbuf(b, x->te_binbuf); //fprintf(stderr, "DONE this must be it\n"); - binbuf_addv(b, ";"); } else if (x->te_type == T_MESSAGE) { @@ -1563,7 +1572,6 @@ void text_save(t_gobj *z, t_binbuf *b) binbuf_addv(b, "ssii", gensym("#X"), gensym("msg"), (int)x->te_xpix, (int)x->te_ypix); binbuf_addbinbuf(b, x->te_binbuf); - binbuf_addv(b, ";"); } else if (x->te_type == T_ATOM) { @@ -1580,7 +1588,6 @@ void text_save(t_gobj *z, t_binbuf *b) (double)((t_gatom *)x)->a_draghi, (double)((t_gatom *)x)->a_wherelabel, label, symfrom, symto); - binbuf_addv(b, ";"); } else { @@ -1609,8 +1616,10 @@ void text_save(t_gobj *z, t_binbuf *b) binbuf_addv(b, "ssii", gensym("#X"), gensym("text"), (int)x->te_xpix, (int)x->te_ypix); binbuf_addbinbuf(b, x->te_binbuf); - binbuf_addv(b, ";"); } + if (x->te_width) + binbuf_addv(b, ",si", gensym("f"), (int)x->te_width); + binbuf_addv(b, ";"); } /* this one is for everyone but "gatoms"; it's imposed in m_class.c */ @@ -1841,48 +1850,33 @@ void text_drawborder(t_text *x, t_glist *glist, } else if (x->te_type == T_MESSAGE) { - msg_draw_const = ((y2-y1)/4); - if (msg_draw_const > 10) msg_draw_const = 10; /* looks bad if too big */ if (firsttime) - { - sys_vgui(".x%lx.c create polygon \ - %d %d %d %d %d %d %d %d %d %d %d %d %d %d \ - -outline $box_outline -fill $msg_box_fill -tags {%sR text}\n", + sys_vgui(".x%lx.c create polygon\ + %d %d %d %d %d %d %d %d %d %d %d %d %d %d -outline $box_outline -fill $msg_box_fill -tags {%sR text}\n", glist_getcanvas(glist), - x1, y1, x2+msg_draw_const, y1, x2, y1+msg_draw_const, - x2, y2-msg_draw_const, x2+msg_draw_const, y2, + x1, y1, x2+4, y1, x2, y1+4, x2, y2-4, x2+4, y2, x1, y2, x1, y1, - tag); - } + tag); else - { sys_vgui(".x%lx.c coords %sR\ %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", glist_getcanvas(glist), tag, - x1, y1, x2+msg_draw_const, y1, x2, y1+msg_draw_const, - x2, y2-msg_draw_const, x2+msg_draw_const, y2, x1, y2, x1, y1); - } + x1, y1, x2+4, y1, x2, y1+4, x2, y2-4, x2+4, y2, + x1, y2, x1, y1); } else if (x->te_type == T_ATOM) { - atom_draw_const = ((y2-y1)/3); if (firsttime) - { - sys_vgui(".x%lx.c create polygon %d %d %d %d %d %d %d %d %d %d %d %d \ - -outline $box_outline -fill $atom_box_fill -tags {%sR text}\n", + sys_vgui(".x%lx.c create polygon\ + %d %d %d %d %d %d %d %d %d %d %d %d -outline $box_outline -fill $atom_box_fill -tags {%sR text}\n", glist_getcanvas(glist), - x1, y1, x2-atom_draw_const, y1, x2, y1+atom_draw_const, - x2, y2, x1, y2, x1, y1, + x1, y1, x2-4, y1, x2, y1+4, x2, y2, x1, y2, x1, y1, tag); - } - else - { + else sys_vgui(".x%lx.c coords %sR\ %d %d %d %d %d %d %d %d %d %d %d %d\n", glist_getcanvas(glist), tag, - x1, y1, x2-atom_draw_const, y1, x2, y1+atom_draw_const, - x2, y2, x1, y2, x1, y1); - } + x1, y1, x2-4, y1, x2, y1+4, x2, y2, x1, y2, x1, y1); } /* draw inlets/outlets */ diff --git a/pd/src/m_binbuf.c b/pd/src/m_binbuf.c index 219505e1ff509e27971d0a1d681552d4288696a0..255e1a48e558efee7a7f9cff95ab495b9205eb5c 100644 --- a/pd/src/m_binbuf.c +++ b/pd/src/m_binbuf.c @@ -174,6 +174,11 @@ void binbuf_text(t_binbuf *x, char *text, size_t size) textp[0]=='@'))) /* JMZ: $@ and $# expansion */ dollar = 1; if (!slash) bufp++; + else if (lastslash) + { + bufp++; + slash = 0; + } } while (textp != etext && bufp != ebuf && (slash || (*textp != ' ' && *textp != '\n' && *textp != '\r' @@ -349,7 +354,8 @@ done: } /* add a binbuf to another one for saving. Semicolons and commas go to -symbols ";", "'",; the symbol ";" goes to "\;", etc. */ +symbols ";", "'",; We assume here (probably incorrectly) that there's +no symbol whose name is ";" - should we be escaping those?. */ void binbuf_addbinbuf(t_binbuf *x, t_binbuf *y) { @@ -391,10 +397,10 @@ void binbuf_addbinbuf(t_binbuf *x, t_binbuf *y) case A_SYMBOL: //fprintf(stderr,"addbinbuf: symbol\n"); /* FIXME make this general */ - if (!strcmp(ap->a_w.w_symbol->s_name, ";")) + /*if (!strcmp(ap->a_w.w_symbol->s_name, ";")) SETSYMBOL(ap, gensym(";")); else if (!strcmp(ap->a_w.w_symbol->s_name, ",")) - SETSYMBOL(ap, gensym(",")); + SETSYMBOL(ap, gensym(","));*/ break; default: bug("binbuf_addbinbuf"); @@ -462,6 +468,23 @@ void binbuf_restore(t_binbuf *x, int argc, t_atom *argv) SETDOLLAR(ap, dollar); } } + else if (strchr(argv->a_w.w_symbol->s_name, '\\')) + { + char buf[MAXPDSTRING], *sp1, *sp2; + int slashed = 0; + for (sp1 = buf, sp2 = argv->a_w.w_symbol->s_name; + *sp2 && sp1 < buf + (MAXPDSTRING-1); + sp2++) + { + if (slashed) + *sp1++ = *sp2; + else if (*sp2 == '\\') + slashed = 1; + else *sp1++ = *sp2, slashed = 0; + } + *sp1 = 0; + SETSYMBOL(ap, gensym(buf)); + } else *ap = *argv; argv++; } @@ -504,6 +527,15 @@ t_atom *binbuf_getvec(t_binbuf *x) return (x->b_vec); } +int binbuf_resize(t_binbuf *x, int newsize) +{ + t_atom *new = t_resizebytes(x->b_vec, + x->b_n * sizeof(*x->b_vec), newsize * sizeof(*x->b_vec)); + if (new) + x->b_vec = new, x->b_n = newsize; + return (new != 0); +} + int canvas_getdollarzero( void); /* JMZ: @@ -873,7 +905,7 @@ broken: static int binbuf_doopen(char *s, int mode) { - char namebuf[FILENAME_MAX]; + char namebuf[MAXPDSTRING]; #ifdef MSW mode |= O_BINARY; #endif @@ -883,7 +915,7 @@ static int binbuf_doopen(char *s, int mode) static FILE *binbuf_dofopen(char *s, char *mode) { - char namebuf[FILENAME_MAX]; + char namebuf[MAXPDSTRING]; sys_bashfilename(s, namebuf); return (fopen(namebuf, mode)); } @@ -894,7 +926,7 @@ int binbuf_read(t_binbuf *b, char *filename, char *dirname, int crflag) int fd; int readret; char *buf; - char namebuf[FILENAME_MAX]; + char namebuf[MAXPDSTRING]; namebuf[0] = 0; if (*dirname) @@ -947,9 +979,9 @@ int binbuf_read_via_canvas(t_binbuf *b, char *filename, t_canvas *canvas, int crflag) { int filedesc; - char buf[FILENAME_MAX], *bufptr; + char buf[MAXPDSTRING], *bufptr; if ((filedesc = canvas_open(canvas, filename, "", - buf, &bufptr, FILENAME_MAX, 0)) < 0) + buf, &bufptr, MAXPDSTRING, 0)) < 0) { error("%s: can't open", filename); return (1); @@ -965,9 +997,9 @@ int binbuf_read_via_path(t_binbuf *b, char *filename, char *dirname, int crflag) { int filedesc; - char buf[FILENAME_MAX], *bufptr; + char buf[MAXPDSTRING], *bufptr; if ((filedesc = open_via_path( - dirname, filename, "", buf, &bufptr, FILENAME_MAX, 0)) < 0) + dirname, filename, "", buf, &bufptr, MAXPDSTRING, 0)) < 0) { error("%s: can't open", filename); return (1); @@ -986,7 +1018,7 @@ static t_binbuf *binbuf_convert(t_binbuf *oldb, int maxtopd); int binbuf_write(t_binbuf *x, char *filename, char *dir, int crflag) { FILE *f = 0; - char sbuf[WBUFSIZE], fbuf[FILENAME_MAX], *bp = sbuf, *ep = sbuf + WBUFSIZE; + char sbuf[WBUFSIZE], fbuf[MAXPDSTRING], *bp = sbuf, *ep = sbuf + WBUFSIZE; t_atom *ap; int indx, deleteit = 0; int ncolumn = 0; @@ -1053,6 +1085,14 @@ int binbuf_write(t_binbuf *x, char *filename, char *dir, int crflag) sys_unixerror(fbuf); goto fail; } + + + if (fflush(f) != 0) + { + sys_unixerror(fbuf); + goto fail; + } + if (deleteit) binbuf_free(x); fclose(f); @@ -1128,7 +1168,7 @@ static t_binbuf *binbuf_convert(t_binbuf *oldb, int maxtopd) { if (stackdepth >= MAXSTACK) { - post("too many embedded patches"); + error("stack depth exceeded: too many embedded patches"); return (newb); } stack[stackdepth] = nobj; @@ -1592,10 +1632,14 @@ void binbuf_evalfile(t_symbol *name, t_symbol *dir) glob_setfilename(0, name, dir); if (binbuf_read(b, name->s_name, dir->s_name, 0)) { - perror(name->s_name); + error("%s: read failed", name->s_name); } else { + /* save bindings of symbols #N, #A (and restore afterward) */ + t_pd *bounda = gensym("#A")->s_thing, *boundn = s__N.s_thing; + gensym("#A")->s_thing = 0; + s__N.s_thing = &pd_canvasmaker; if (import) { t_binbuf *newb = binbuf_convert(b, 1); @@ -1603,13 +1647,15 @@ void binbuf_evalfile(t_symbol *name, t_symbol *dir) b = newb; } binbuf_eval(b, 0, 0, 0); + gensym("#A")->s_thing = bounda; + s__N.s_thing = boundn; } glob_setfilename(0, &s_, &s_); binbuf_free(b); canvas_resume_dsp(dspstate); } -void glob_evalfile(t_pd *ignore, t_symbol *name, t_symbol *dir) +t_pd *glob_evalfile(t_pd *ignore, t_symbol *name, t_symbol *dir) { t_pd *x = 0; /* even though binbuf_evalfile appears to take care of dspstate, @@ -1618,9 +1664,17 @@ void glob_evalfile(t_pd *ignore, t_symbol *name, t_symbol *dir) is still necessary -- probably not. */ int dspstate = canvas_suspend_dsp(); + t_pd *boundx = s__X.s_thing; + s__X.s_thing = 0; /* don't save #X; we'll need to leave it bound + for the caller to grab it. */ binbuf_evalfile(name, dir); - while ((x != s__X.s_thing) && (x = s__X.s_thing)) + while ((x != s__X.s_thing) && s__X.s_thing) + { + x = s__X.s_thing; vmess(x, gensym("pop"), "i", 1); + } pd_doloadbang(); canvas_resume_dsp(dspstate); + s__X.s_thing = boundx; + return x; } diff --git a/pd/src/pd.tk b/pd/src/pd.tk index b3f624a73ea93e82c376bc7d5b0fe04294b7a7a2..ae3dcd5b96e1d9ecb6326b9c53e4fffd2bca826c 100644 --- a/pd/src/pd.tk +++ b/pd/src/pd.tk @@ -204,6 +204,8 @@ if { $tcl_platform(platform) == "windows" } { set cursor_editmode_nothing "hand2" set cursor_editmode_connect "circle" set cursor_editmode_disconnect "X_cursor" + set cursor_editmode_resize "sb_h_double_arrow" + set cursor_editmode_resize_bottom_right "bottom_right_corner" # set file types that open/save recognize set filetypes { {{Pd Files} {.pd} } @@ -230,6 +232,8 @@ if { $tcl_platform(platform) == "windows" } { set cursor_editmode_nothing "hand2" set cursor_editmode_connect "circle" set cursor_editmode_disconnect "X_cursor" + set cursor_editmode_resize "sb_h_double_arrow" + set cursor_editmode_resize_bottom_right "bottom_right_corner" # set file types that open/save recognize set filetypes { {{Pd Files} {.pd} } @@ -262,6 +266,8 @@ if { $tcl_platform(platform) == "windows" } { set cursor_editmode_nothing "hand2" set cursor_editmode_connect "target" set cursor_editmode_disconnect "X_cursor" + set cursor_editmode_resize "sb_h_double_arrow" + set cursor_editmode_resize_bottom_right "bottom_right_corner" # set file types that open/save recognize set filetypes { {{pd files} {.pd} }