Update of /cvsroot/pure-data/pd/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26921
Modified Files: Tag: devel_0_39 SConscript desire.c Log Message: merged impd's g_rtext.c
Index: SConscript =================================================================== RCS file: /cvsroot/pure-data/pd/src/Attic/SConscript,v retrieving revision 1.1.4.21 retrieving revision 1.1.4.22 diff -C2 -d -r1.1.4.21 -r1.1.4.22 *** SConscript 8 Sep 2005 07:42:30 -0000 1.1.4.21 --- SConscript 8 Sep 2005 08:52:46 -0000 1.1.4.22 *************** *** 47,51 **** d_soundfile.c d_ugen.c - g_all_guis.c g_array.c g_canvas.c --- 47,50 ---- *************** *** 55,59 **** g_io.c g_readwrite.c - g_rtext.c g_scalar.c g_template.c --- 54,57 ---- *************** *** 99,103 **** g_bang.c g_hdial.c g_hslider.c g_mycanvas.c g_numbox.c g_vdial.c g_vslider.c g_vumeter.c ! g_text.c g_toggle.c """)
--- 97,101 ---- g_bang.c g_hdial.c g_hslider.c g_mycanvas.c g_numbox.c g_vdial.c g_vslider.c g_vumeter.c ! g_text.c g_toggle.c g_rtext.c g_all_guis.c """)
*************** *** 226,229 **** --- 224,230 ---- defs.append('LOCKFREE')
+ if pdenv['desire']: + defs.append('DESIRE') + pdenv.Append(CPPDEFINES=defs)
Index: desire.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/Attic/desire.c,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -C2 -d -r1.1.2.2 -r1.1.2.3 *** desire.c 8 Sep 2005 08:41:09 -0000 1.1.2.2 --- desire.c 8 Sep 2005 08:52:46 -0000 1.1.2.3 *************** *** 19,23 **** #include <math.h> #include <stdarg.h> - #include <stdlib.h> #include "m_pd.h" --- 19,22 ---- *************** *** 28,31 **** --- 27,448 ---- #include <string.h> #include <math.h> + #include <stdlib.h> + #include <string.h> + #include <stdio.h> + #include <ctype.h> + #include "m_pd.h" + #include "s_stuff.h" + #include "g_canvas.h" + #include "t_tk.h" + + #define LMARGIN 1 + #define RMARGIN 1 + #define TMARGIN 2 + #define BMARGIN 2 + + #define SEND_FIRST 1 + #define SEND_UPDATE 2 + #define SEND_CHECK 0 + + struct _rtext + { + char *x_buf; + int x_bufsize; + int x_selstart; + int x_selend; + int x_active; + int x_dragfrom; + int x_height; + int x_drawnwidth; + int x_drawnheight; + t_text *x_text; + t_glist *x_glist; + char x_tag[50]; + struct _rtext *x_next; + }; + + t_rtext *rtext_new(t_glist *glist, t_text *who) + { + t_rtext *x = (t_rtext *)getbytes(sizeof *x); + x->x_height = -1; + x->x_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; + binbuf_gettext(who->te_binbuf, &x->x_buf, &x->x_bufsize); + glist->gl_editor->e_rtext = x; + sprintf(x->x_tag, "%xTEXT", x->x_text); + return (x); + } + + void rtext_free(t_rtext *x) + { + t_editor *e = x->x_glist->gl_editor; + if (e->e_textedfor == x) e->e_textedfor = 0; + if (e->e_rtext == x) e->e_rtext = x->x_next; + else + { + t_rtext *e2; + for (e2 = e->e_rtext; e2; e2 = e2->x_next) + if (e2->x_next == x) {e2->x_next = x->x_next; break;} + } + freebytes(x->x_buf, x->x_bufsize); + freebytes(x, sizeof *x); + } + + char *rtext_gettag(t_rtext *x) + { + return x->x_tag; + } + + void rtext_gettext(t_rtext *x, char **buf, int *bufsize) + { + *buf = x->x_buf; + *bufsize = x->x_bufsize; + } + + /* LATER deal with tcl-significant characters */ + static int firstone(char *s, int c, int n) + { + char *s2 = s + n; + int i = 0; + while (s != s2) + { + if (*s == c) return (i); + i++; + s++; + } + return (-1); + } + + static int lastone(char *s, int c, int n) + { + char *s2 = s + n; + while (s2 != s) {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. + 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 + of the entire text in pixels. + */ + + #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; + + 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; + 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; + 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 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++; + } + outchars = tp - tempbuf; + if (outchars > 1950) outchars = 1950; + if (!reportedindex) + *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++;} + } + else ncolumns = widthspec; + pixwide = ncolumns * fontwidth + (LMARGIN + RMARGIN); + pixhigh = nlines * fontheight + (TMARGIN + BMARGIN); + if (action == SEND_FIRST) { + sys_vgui("global look; 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) ? + "$look(objectfgsel)" : "$look(objectfg)"); + } + 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); + } + } + } + x->x_drawnwidth = pixwide; + x->x_drawnheight = pixhigh; + *widthp = pixwide; + *heightp = pixhigh; + } + + void rtext_retext(t_rtext *x) + { + int w = 0, h = 0, indx; + 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. */ + if (text->te_width > 0 && text->te_type == T_ATOM && + 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; + 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; + } + rtext_senditup(x, SEND_UPDATE, &w, &h, &indx); + } + + /* find the rtext that goes with a text item */ + t_rtext *glist_findrtext(t_glist *gl, t_text *who) + { + t_rtext *x = gl->gl_editor->e_rtext; + while (x && x->x_text != who) x = x->x_next; + if (!x) bug("glist_findrtext"); + return (x); + } + + int rtext_width(t_rtext *x) {int w=0, h=0, i; rtext_senditup(x, SEND_CHECK, &w, &h, &i); return w;} + int rtext_height(t_rtext *x) {int w=0, h=0, i; rtext_senditup(x, SEND_CHECK, &w, &h, &i); return h;} + void rtext_draw(t_rtext *x) {int w=0, h=0, i; rtext_senditup(x, SEND_FIRST, &w, &h, &i);} + + void rtext_erase(t_rtext *x) + {sys_vgui("pdtk_text_delete .x%x.c %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);} + + void rtext_select(t_rtext *x, int state) + {t_canvas *canvas = glist_getcanvas(x->x_glist); + sys_vgui(".x%x.c itemconfigure %s -fill %s\n", canvas, + x->x_tag, (state? "blue" : "black")); + canvas_editing = canvas; + } + + void rtext_activate(t_rtext *x, int state) + { + int w = 0, h = 0, indx; + t_glist *glist = x->x_glist; + t_canvas *canvas = glist_getcanvas(glist); + t_editor *e = glist->gl_editor; + if (state) + { + sys_vgui(".x%x.c focus %s\n", canvas, x->x_tag); + e->e_textedfor = x; + e->e_textdirty = 0; + x->x_dragfrom = x->x_selstart = 0; + x->x_selend = x->x_bufsize; + } + else + { + sys_vgui("selection clear .x%x.c\n", canvas); + sys_vgui(".x%x.c focus ""\n", canvas); + if (e->e_textedfor == x) e->e_textedfor = 0; + } + x->x_active = !!state; + rtext_senditup(x, SEND_UPDATE, &w, &h, &indx); + } + + void rtext_key(t_rtext *x, int keynum, t_symbol *keysym) + { + int w = 0, h = 0, indx, i, newsize, ndel; + t_glist *glist = x->x_glist; + t_canvas *canvas = glist_getcanvas(glist); + if (keynum) + { + int n = keynum; + if (n == '\r') n = '\n'; + if (n == '\t') { + sys_vgui("propose_completions %x .x%x.c %d %d {%.*s}\n", x, canvas, + text_xpix(x->x_text, x->x_glist) + x->x_drawnwidth, + text_ypix(x->x_text, x->x_glist) + x->x_drawnheight/2, + x->x_bufsize, x->x_buf); + } + 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; + } + 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; + } + /* 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; + } + 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; + } + else { + post("<%s>: dropped",keysym->s_name); + } + rtext_senditup(x, SEND_UPDATE, &w, &h, &indx); + } + + void rtext_mouse(t_rtext *x, int xval, int yval, int flag) + { + int w = xval, h = yval, indx; + rtext_senditup(x, SEND_CHECK, &w, &h, &indx); + if (flag == RTEXT_DOWN) + { + x->x_dragfrom = x->x_selstart = x->x_selend = indx; + } + 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; + } + } + 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; + } + rtext_senditup(x, SEND_UPDATE, &w, &h, &indx); + } + + // up: g_rtext + //--------------------------------------------------------------------------------------------------------- + // down: g_text
/*static*/ t_class *text_class;