diff options
Diffstat (limited to 'pd/src/g_rtext.c')
-rw-r--r-- | pd/src/g_rtext.c | 500 |
1 files changed, 277 insertions, 223 deletions
diff --git a/pd/src/g_rtext.c b/pd/src/g_rtext.c index d44f30fa..0de6903e 100644 --- a/pd/src/g_rtext.c +++ b/pd/src/g_rtext.c @@ -50,11 +50,11 @@ t_rtext *rtext_new(t_glist *glist, t_text *who) x->x_glist = glist; x->x_next = glist->gl_editor->e_rtext; x->x_selstart = x->x_selend = x->x_active = - x->x_drawnwidth = x->x_drawnheight = 0; + x->x_drawnwidth = x->x_drawnheight = 0; binbuf_gettext(who->te_binbuf, &x->x_buf, &x->x_bufsize); glist->gl_editor->e_rtext = x; - sprintf(x->x_tag, ".x%x.t%x", (t_int)glist_getcanvas(x->x_glist), - (t_int)x); + sprintf(x->x_tag, ".x%lx.t%lx", (t_int)glist_getcanvas(x->x_glist), + (t_int)x); return (x); } @@ -63,18 +63,18 @@ static t_rtext *rtext_entered; void rtext_free(t_rtext *x) { if (x->x_glist->gl_editor->e_textedfor == x) - x->x_glist->gl_editor->e_textedfor = 0; + x->x_glist->gl_editor->e_textedfor = 0; if (x->x_glist->gl_editor->e_rtext == x) - x->x_glist->gl_editor->e_rtext = x->x_next; + x->x_glist->gl_editor->e_rtext = x->x_next; else { - t_rtext *e2; - for (e2 = x->x_glist->gl_editor->e_rtext; e2; e2 = e2->x_next) - if (e2->x_next == x) - { - e2->x_next = x->x_next; - break; - } + t_rtext *e2; + for (e2 = x->x_glist->gl_editor->e_rtext; e2; e2 = e2->x_next) + if (e2->x_next == x) + { + e2->x_next = x->x_next; + break; + } } if (rtext_entered == x) rtext_entered = 0; freebytes(x->x_buf, x->x_bufsize); @@ -92,6 +92,11 @@ void rtext_gettext(t_rtext *x, char **buf, int *bufsize) *bufsize = x->x_bufsize; } +void rtext_getseltext(t_rtext *x, char **buf, int *bufsize) +{ + *buf = x->x_buf + x->x_selstart; + *bufsize = x->x_selend - x->x_selstart; +} /* LATER deal with tcl-significant characters */ @@ -101,9 +106,9 @@ static int firstone(char *s, int c, int n) int i = 0; while (s != s2) { - if (*s == c) return (i); - i++; - s++; + if (*s == c) return (i); + i++; + s++; } return (-1); } @@ -113,18 +118,18 @@ static int lastone(char *s, int c, int n) char *s2 = s + n; while (s2 != s) { - s2--; - n--; - if (*s2 == c) return (n); + s2--; + n--; + if (*s2 == c) return (n); } return (-1); } /* the following routine computes line breaks and carries out some action which could be: - SEND_FIRST - draw the box for the first time - SEND_UPDATE - redraw the updated box - otherwise - don't draw, just calculate. + 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 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 @@ -132,125 +137,138 @@ static int lastone(char *s, int c, int n) */ /* LATER get this and sys_vgui to work together properly, - breaking up messages as needed. As of now, there's - a limit of 1950 characters, imposed by sys_vgui(). */ + breaking up messages as needed. As of now, there's + a limit of 1950 characters, imposed by sys_vgui(). */ #define UPBUFSIZE 4000 #define BOXWIDTH 60 /* Older (pre-8.3.4) TCL versions handle text selection differently; this flag is set from the GUI if this happens. LATER take this out: early 2006? */ -extern int sys_oldtclversion; +extern int sys_oldtclversion; static void rtext_senditup(t_rtext *x, int action, int *widthp, int *heightp, int *indexp) { float dispx, dispy; - char tempbuf[UPBUFSIZE], *tp = tempbuf, *bp = x->x_buf; - int outchars, inchars = x->x_bufsize, nlines = 0, ncolumns = 0, - pixwide, pixhigh; + char smallbuf[200], *tempbuf; + int outchars = 0, nlines = 0, ncolumns = 0, + pixwide, pixhigh; int font = glist_getfont(x->x_glist); int fontwidth = sys_fontwidth(font), fontheight = sys_fontheight(font); int findx = (*widthp + (fontwidth/2)) / fontwidth, - findy = *heightp / fontheight; + findy = *heightp / fontheight; int reportedindex = 0; t_canvas *canvas = glist_getcanvas(x->x_glist); int widthspec = x->x_text->te_width; int widthlimit = (widthspec ? widthspec : BOXWIDTH); - while (inchars) + int inindex = 0; + int selstart = 0, selend = 0; + if (x->x_bufsize >= 100) + tempbuf = (char *)t_getbytes(2 * x->x_bufsize + 1); + else tempbuf = smallbuf; + while (x->x_bufsize - inindex > 0) { - int maxindex = (inchars > widthlimit ? widthlimit : inchars); - int eatchar = 1; - int foundit = firstone(bp, '\n', maxindex); - if (foundit < 0) - { - if (inchars > widthlimit) - { - foundit = lastone(bp, ' ', maxindex); - if (foundit < 0) - { - foundit = maxindex; - eatchar = 0; - } - } - else - { - foundit = inchars; - eatchar = 0; - } - } - if (nlines == findy) - { - int actualx = (findx < 0 ? 0 : - (findx > foundit ? foundit : findx)); - *indexp = (bp - x->x_buf) + actualx; - reportedindex = 1; - } - strncpy(tp, bp, foundit); - tp += foundit; - bp += (foundit + eatchar); - inchars -= (foundit + eatchar); - if (inchars) *tp++ = '\n'; - if (foundit > ncolumns) ncolumns = foundit; - nlines++; + int inchars = x->x_bufsize - inindex; + int maxindex = (inchars > widthlimit ? widthlimit : inchars); + int eatchar = 1; + int foundit = firstone(x->x_buf + inindex, '\n', maxindex); + if (foundit < 0) + { + if (inchars > widthlimit) + { + foundit = lastone(x->x_buf + inindex, ' ', maxindex); + if (foundit < 0) + { + foundit = maxindex; + eatchar = 0; + } + } + else + { + foundit = inchars; + eatchar = 0; + } + } + if (nlines == findy) + { + int actualx = (findx < 0 ? 0 : + (findx > foundit ? foundit : findx)); + *indexp = inindex + actualx; + reportedindex = 1; + } + strncpy(tempbuf+outchars, x->x_buf + inindex, foundit); + if (x->x_selstart >= inindex && + x->x_selstart <= inindex + foundit + eatchar) + selstart = x->x_selstart + outchars - inindex; + if (x->x_selend >= inindex && + x->x_selend <= inindex + foundit + eatchar) + selend = x->x_selend + outchars - inindex; + outchars += foundit; + inindex += (foundit + eatchar); + if (inindex < x->x_bufsize) + tempbuf[outchars++] = '\n'; + if (foundit > ncolumns) + ncolumns = foundit; + nlines++; } - outchars = tp - tempbuf; - if (outchars > 1950) outchars = 1950; if (!reportedindex) - *indexp = outchars; + *indexp = outchars; dispx = text_xpix(x->x_text, x->x_glist); dispy = text_ypix(x->x_text, x->x_glist); if (nlines < 1) nlines = 1; if (!widthspec) { - while (ncolumns < 3) - { - tempbuf[outchars++] = ' '; - ncolumns++; - } + while (ncolumns < 3) + { + tempbuf[outchars++] = ' '; + ncolumns++; + } } else ncolumns = widthspec; pixwide = ncolumns * fontwidth + (LMARGIN + RMARGIN); pixhigh = nlines * fontheight + (TMARGIN + BMARGIN); if (action == SEND_FIRST) - sys_vgui("pdtk_text_new .x%x.c %s %f %f {%.*s} %d %s\n", - canvas, x->x_tag, - dispx + LMARGIN, dispy + TMARGIN, - outchars, tempbuf, sys_hostfontsize(font), - (glist_isselected(x->x_glist, - &x->x_glist->gl_gobj)? "blue" : "black")); + sys_vgui("pdtk_text_new .x%lx.c %s %f %f {%.*s} %d %s\n", + canvas, x->x_tag, + dispx + LMARGIN, dispy + TMARGIN, + outchars, tempbuf, sys_hostfontsize(font), + (glist_isselected(x->x_glist, + &x->x_glist->gl_gobj)? "blue" : "black")); else if (action == SEND_UPDATE) { - sys_vgui("pdtk_text_set .x%x.c %s {%.*s}\n", - canvas, x->x_tag, outchars, tempbuf); - if (pixwide != x->x_drawnwidth || pixhigh != x->x_drawnheight) - text_drawborder(x->x_text, x->x_glist, x->x_tag, - pixwide, pixhigh, 0); - if (x->x_active) - { - if (x->x_selend > x->x_selstart) - { - sys_vgui(".x%x.c select from %s %d\n", canvas, - x->x_tag, x->x_selstart); - sys_vgui(".x%x.c select to %s %d\n", canvas, - x->x_tag, x->x_selend + (sys_oldtclversion ? 0 : -1)); - sys_vgui(".x%x.c focus \"\"\n", canvas); - } - else - { - sys_vgui(".x%x.c select clear\n", canvas); - sys_vgui(".x%x.c icursor %s %d\n", canvas, x->x_tag, - x->x_selstart); - sys_vgui(".x%x.c focus %s\n", canvas, x->x_tag); - } - } + sys_vgui("pdtk_text_set .x%lx.c %s {%.*s}\n", + canvas, x->x_tag, outchars, tempbuf); + if (pixwide != x->x_drawnwidth || pixhigh != x->x_drawnheight) + text_drawborder(x->x_text, x->x_glist, x->x_tag, + pixwide, pixhigh, 0); + if (x->x_active) + { + if (selend > selstart) + { + sys_vgui(".x%lx.c select from %s %d\n", canvas, + x->x_tag, selstart); + sys_vgui(".x%lx.c select to %s %d\n", canvas, + x->x_tag, selend + (sys_oldtclversion ? 0 : -1)); + sys_vgui(".x%lx.c focus \"\"\n", canvas); + } + else + { + sys_vgui(".x%lx.c select clear\n", canvas); + sys_vgui(".x%lx.c icursor %s %d\n", canvas, x->x_tag, + selstart); + sys_vgui(".x%lx.c focus %s\n", canvas, x->x_tag); + } + } } x->x_drawnwidth = pixwide; x->x_drawnheight = pixhigh; *widthp = pixwide; *heightp = pixhigh; + if (tempbuf != smallbuf) + t_freebytes(tempbuf, 2 * x->x_bufsize + 1); } void rtext_retext(t_rtext *x) @@ -259,51 +277,51 @@ void rtext_retext(t_rtext *x) t_text *text = x->x_text; t_freebytes(x->x_buf, x->x_bufsize); binbuf_gettext(text->te_binbuf, &x->x_buf, &x->x_bufsize); - /* special case: for number boxes, try to pare the number down - to the specified width of the box. */ + /* special case: for number boxes, try to pare the number down + to the specified width of the box. */ if (text->te_width > 0 && text->te_type == T_ATOM && - x->x_bufsize > text->te_width) + x->x_bufsize > text->te_width) { - t_atom *atomp = binbuf_getvec(text->te_binbuf); - int natom = binbuf_getnatom(text->te_binbuf); - int bufsize = x->x_bufsize; - if (natom == 1 && atomp->a_type == A_FLOAT) - { - /* try to reduce size by dropping decimal digits */ - int wantreduce = bufsize - text->te_width; - char *decimal = 0, *nextchar, *ebuf = x->x_buf + bufsize, - *s1, *s2; - int ndecimals; - for (decimal = x->x_buf; decimal < ebuf; decimal++) - if (*decimal == '.') - break; - if (decimal >= ebuf) - goto giveup; - for (nextchar = decimal + 1; nextchar < ebuf; nextchar++) - if (*nextchar < '0' || *nextchar > '9') - break; - if (nextchar - decimal - 1 < wantreduce) - goto giveup; - for (s1 = nextchar - wantreduce, s2 = s1 + wantreduce; - s2 < ebuf; s1++, s2++) - *s1 = *s2; - t_resizebytes(x->x_buf, bufsize, text->te_width); - bufsize = text->te_width; - goto done; - giveup: - /* give up and bash it to "+" or "-" */ - x->x_buf[0] = (atomp->a_w.w_float < 0 ? '-' : '+'); - t_resizebytes(x->x_buf, bufsize, 1); - bufsize = 1; - } - else if (bufsize > text->te_width) - { - x->x_buf[text->te_width - 1] = '>'; - t_resizebytes(x->x_buf, bufsize, text->te_width); - bufsize = text->te_width; - } + t_atom *atomp = binbuf_getvec(text->te_binbuf); + int natom = binbuf_getnatom(text->te_binbuf); + int bufsize = x->x_bufsize; + if (natom == 1 && atomp->a_type == A_FLOAT) + { + /* try to reduce size by dropping decimal digits */ + int wantreduce = bufsize - text->te_width; + char *decimal = 0, *nextchar, *ebuf = x->x_buf + bufsize, + *s1, *s2; + int ndecimals; + for (decimal = x->x_buf; decimal < ebuf; decimal++) + if (*decimal == '.') + break; + if (decimal >= ebuf) + goto giveup; + for (nextchar = decimal + 1; nextchar < ebuf; nextchar++) + if (*nextchar < '0' || *nextchar > '9') + break; + if (nextchar - decimal - 1 < wantreduce) + goto giveup; + for (s1 = nextchar - wantreduce, s2 = s1 + wantreduce; + s2 < ebuf; s1++, s2++) + *s1 = *s2; + t_resizebytes(x->x_buf, bufsize, text->te_width); + bufsize = text->te_width; + goto done; + giveup: + /* give up and bash it to "+" or "-" */ + x->x_buf[0] = (atomp->a_w.w_float < 0 ? '-' : '+'); + t_resizebytes(x->x_buf, bufsize, 1); + bufsize = 1; + } + else if (bufsize > text->te_width) + { + x->x_buf[text->te_width - 1] = '>'; + t_resizebytes(x->x_buf, bufsize, text->te_width); + bufsize = text->te_width; + } done: - x->x_bufsize = bufsize; + x->x_bufsize = bufsize; } rtext_senditup(x, SEND_UPDATE, &w, &h, &indx); } @@ -339,21 +357,21 @@ void rtext_draw(t_rtext *x) void rtext_erase(t_rtext *x) { - sys_vgui(".x%x.c delete %s\n", glist_getcanvas(x->x_glist), x->x_tag); + sys_vgui(".x%lx.c delete %s\n", glist_getcanvas(x->x_glist), x->x_tag); } void rtext_displace(t_rtext *x, int dx, int dy) { - sys_vgui(".x%x.c move %s %d %d\n", glist_getcanvas(x->x_glist), - x->x_tag, dx, dy); + sys_vgui(".x%lx.c move %s %d %d\n", glist_getcanvas(x->x_glist), + x->x_tag, dx, dy); } void rtext_select(t_rtext *x, int state) { t_glist *glist = x->x_glist; t_canvas *canvas = glist_getcanvas(glist); - sys_vgui(".x%x.c itemconfigure %s -fill %s\n", canvas, - x->x_tag, (state? "blue" : "black")); + sys_vgui(".x%lx.c itemconfigure %s -fill %s\n", canvas, + x->x_tag, (state? "blue" : "black")); canvas_editing = canvas; } @@ -364,20 +382,20 @@ void rtext_activate(t_rtext *x, int state) t_canvas *canvas = glist_getcanvas(glist); if (state) { - sys_vgui(".x%x.c focus %s\n", canvas, x->x_tag); - glist->gl_editor->e_textedfor = x; - glist->gl_editor->e_textdirty = 0; - x->x_dragfrom = x->x_selstart = 0; - x->x_selend = x->x_bufsize; - x->x_active = 1; + sys_vgui(".x%lx.c focus %s\n", canvas, x->x_tag); + glist->gl_editor->e_textedfor = x; + glist->gl_editor->e_textdirty = 0; + x->x_dragfrom = x->x_selstart = 0; + x->x_selend = x->x_bufsize; + x->x_active = 1; } else { - sys_vgui("selection clear .x%x.c\n", canvas); - sys_vgui(".x%x.c focus \"\"\n", canvas); - if (glist->gl_editor->e_textedfor == x) - glist->gl_editor->e_textedfor = 0; - x->x_active = 0; + sys_vgui("selection clear .x%lx.c\n", canvas); + sys_vgui(".x%lx.c focus \"\"\n", canvas); + if (glist->gl_editor->e_textedfor == x) + glist->gl_editor->e_textedfor = 0; + x->x_active = 0; } rtext_senditup(x, SEND_UPDATE, &w, &h, &indx); } @@ -388,76 +406,76 @@ void rtext_key(t_rtext *x, int keynum, t_symbol *keysym) char *s1, *s2; if (keynum) { - int n = keynum; - if (n == '\r') n = '\n'; - if (n == '\b') /* backspace */ - { - /* LATER delete the box if all text is selected... - this causes reentrancy problems now. */ - /* if ((!x->x_selstart) && (x->x_selend == x->x_bufsize)) - { - .... - } */ - if (x->x_selstart && (x->x_selstart == x->x_selend)) - x->x_selstart--; - } - else if (n == 127) /* delete */ - { - if (x->x_selend < x->x_bufsize && (x->x_selstart == x->x_selend)) - x->x_selend++; - } - - ndel = x->x_selend - x->x_selstart; - for (i = x->x_selend; i < x->x_bufsize; i++) - x->x_buf[i- ndel] = x->x_buf[i]; - newsize = x->x_bufsize - ndel; - x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize); - x->x_bufsize = newsize; - - if (n == '\n' || isprint(n)) - { - newsize = x->x_bufsize+1; - x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize); - for (i = x->x_bufsize; i > x->x_selstart; i--) - x->x_buf[i] = x->x_buf[i-1]; - x->x_buf[x->x_selstart] = n; - x->x_bufsize = newsize; - x->x_selstart = x->x_selstart + 1; - } - x->x_selend = x->x_selstart; - x->x_glist->gl_editor->e_textdirty = 1; + int n = keynum; + if (n == '\r') n = '\n'; + if (n == '\b') /* backspace */ + { + /* LATER delete the box if all text is selected... + this causes reentrancy problems now. */ + /* if ((!x->x_selstart) && (x->x_selend == x->x_bufsize)) + { + .... + } */ + if (x->x_selstart && (x->x_selstart == x->x_selend)) + x->x_selstart--; + } + else if (n == 127) /* delete */ + { + if (x->x_selend < x->x_bufsize && (x->x_selstart == x->x_selend)) + x->x_selend++; + } + + ndel = x->x_selend - x->x_selstart; + for (i = x->x_selend; i < x->x_bufsize; i++) + x->x_buf[i- ndel] = x->x_buf[i]; + newsize = x->x_bufsize - ndel; + x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize); + x->x_bufsize = newsize; + + if (n == '\n' || isprint(n)) + { + newsize = x->x_bufsize+1; + x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize); + for (i = x->x_bufsize; i > x->x_selstart; i--) + x->x_buf[i] = x->x_buf[i-1]; + x->x_buf[x->x_selstart] = n; + x->x_bufsize = newsize; + x->x_selstart = x->x_selstart + 1; + } + x->x_selend = x->x_selstart; + x->x_glist->gl_editor->e_textdirty = 1; } else if (!strcmp(keysym->s_name, "Right")) { - if (x->x_selend == x->x_selstart && x->x_selstart < x->x_bufsize) - x->x_selend = x->x_selstart = x->x_selstart + 1; - else - x->x_selstart = x->x_selend; + if (x->x_selend == x->x_selstart && x->x_selstart < x->x_bufsize) + x->x_selend = x->x_selstart = x->x_selstart + 1; + else + x->x_selstart = x->x_selend; } else if (!strcmp(keysym->s_name, "Left")) { - if (x->x_selend == x->x_selstart && x->x_selstart > 0) - x->x_selend = x->x_selstart = x->x_selstart - 1; - else - x->x_selend = x->x_selstart; + if (x->x_selend == x->x_selstart && x->x_selstart > 0) + x->x_selend = x->x_selstart = x->x_selstart - 1; + else + x->x_selend = x->x_selstart; } - /* this should be improved... life's too short */ + /* this should be improved... life's too short */ else if (!strcmp(keysym->s_name, "Up")) { - if (x->x_selstart) - x->x_selstart--; - while (x->x_selstart > 0 && x->x_buf[x->x_selstart] != '\n') - x->x_selstart--; - x->x_selend = x->x_selstart; + if (x->x_selstart) + x->x_selstart--; + while (x->x_selstart > 0 && x->x_buf[x->x_selstart] != '\n') + x->x_selstart--; + x->x_selend = x->x_selstart; } else if (!strcmp(keysym->s_name, "Down")) { - while (x->x_selend < x->x_bufsize && - x->x_buf[x->x_selend] != '\n') - x->x_selend++; - if (x->x_selend < x->x_bufsize) - x->x_selend++; - x->x_selstart = x->x_selend; + while (x->x_selend < x->x_bufsize && + x->x_buf[x->x_selend] != '\n') + x->x_selend++; + if (x->x_selend < x->x_bufsize) + x->x_selend++; + x->x_selstart = x->x_selend; } rtext_senditup(x, SEND_UPDATE, &w, &h, &indx); } @@ -468,19 +486,55 @@ void rtext_mouse(t_rtext *x, int xval, int yval, int flag) rtext_senditup(x, SEND_CHECK, &w, &h, &indx); if (flag == RTEXT_DOWN) { - x->x_dragfrom = x->x_selstart = x->x_selend = indx; + x->x_dragfrom = x->x_selstart = x->x_selend = indx; + } + else if (flag == RTEXT_DBL) + { + int whereseparator, newseparator; + x->x_dragfrom = -1; + whereseparator = 0; + if ((newseparator = lastone(x->x_buf, ' ', indx)) > whereseparator) + whereseparator = newseparator+1; + if ((newseparator = lastone(x->x_buf, '\n', indx)) > whereseparator) + whereseparator = newseparator+1; + if ((newseparator = lastone(x->x_buf, ';', indx)) > whereseparator) + whereseparator = newseparator+1; + if ((newseparator = lastone(x->x_buf, ',', indx)) > whereseparator) + whereseparator = newseparator+1; + x->x_selstart = whereseparator; + + whereseparator = x->x_bufsize - indx; + if ((newseparator = + firstone(x->x_buf+indx, ' ', x->x_bufsize - indx)) >= 0 && + newseparator < whereseparator) + whereseparator = newseparator; + if ((newseparator = + firstone(x->x_buf+indx, '\n', x->x_bufsize - indx)) >= 0 && + newseparator < whereseparator) + whereseparator = newseparator; + if ((newseparator = + firstone(x->x_buf+indx, ';', x->x_bufsize - indx)) >= 0 && + newseparator < whereseparator) + whereseparator = newseparator; + if ((newseparator = + firstone(x->x_buf+indx, ',', x->x_bufsize - indx)) >= 0 && + newseparator < whereseparator) + whereseparator = newseparator; + x->x_selend = indx + whereseparator; } else if (flag == RTEXT_SHIFT) { - if (indx * 2 > x->x_selstart + x->x_selend) - x->x_dragfrom = x->x_selstart, x->x_selend = indx; - else - x->x_dragfrom = x->x_selend, x->x_selstart = indx; + if (indx * 2 > x->x_selstart + x->x_selend) + x->x_dragfrom = x->x_selstart, x->x_selend = indx; + else + x->x_dragfrom = x->x_selend, x->x_selstart = indx; } else if (flag == RTEXT_DRAG) { - x->x_selstart = (x->x_dragfrom < indx ? x->x_dragfrom : indx); - x->x_selend = (x->x_dragfrom > indx ? x->x_dragfrom : indx); + if (x->x_dragfrom < 0) + return; + x->x_selstart = (x->x_dragfrom < indx ? x->x_dragfrom : indx); + x->x_selend = (x->x_dragfrom > indx ? x->x_dragfrom : indx); } rtext_senditup(x, SEND_UPDATE, &w, &h, &indx); } |