1 /* Copyright (c) 1997-1999 Miller Puckette.
2 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
3 * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
5 /* changes by Thomas Musil IEM KUG Graz Austria 2001 */
6 /* have to insert gui-objects into editor-list */
7 /* all changes are labeled with iemlib */
41 struct _rtext
*x_next
;
44 t_rtext
*rtext_new(t_glist
*glist
, t_text
*who
)
46 t_rtext
*x
= (t_rtext
*)getbytes(sizeof *x
);
47 int w
= 0, h
= 0, indx
;
51 x
->x_next
= glist
->gl_editor
->e_rtext
;
52 x
->x_selstart
= x
->x_selend
= x
->x_active
=
53 x
->x_drawnwidth
= x
->x_drawnheight
= 0;
54 binbuf_gettext(who
->te_binbuf
, &x
->x_buf
, &x
->x_bufsize
);
55 glist
->gl_editor
->e_rtext
= x
;
56 sprintf(x
->x_tag
, ".x%x.t%x", (t_int
)glist_getcanvas(x
->x_glist
),
61 static t_rtext
*rtext_entered
;
63 void rtext_free(t_rtext
*x
)
65 if (x
->x_glist
->gl_editor
->e_textedfor
== x
)
66 x
->x_glist
->gl_editor
->e_textedfor
= 0;
67 if (x
->x_glist
->gl_editor
->e_rtext
== x
)
68 x
->x_glist
->gl_editor
->e_rtext
= x
->x_next
;
72 for (e2
= x
->x_glist
->gl_editor
->e_rtext
; e2
; e2
= e2
->x_next
)
75 e2
->x_next
= x
->x_next
;
79 if (rtext_entered
== x
) rtext_entered
= 0;
80 freebytes(x
->x_buf
, x
->x_bufsize
);
81 freebytes(x
, sizeof *x
);
84 char *rtext_gettag(t_rtext
*x
)
89 void rtext_gettext(t_rtext
*x
, char **buf
, int *bufsize
)
92 *bufsize
= x
->x_bufsize
;
96 /* LATER deal with tcl-significant characters */
98 static int firstone(char *s
, int c
, int n
)
104 if (*s
== c
) return (i
);
111 static int lastone(char *s
, int c
, int n
)
118 if (*s2
== c
) return (n
);
123 /* the following routine computes line breaks and carries out
124 some action which could be:
125 SEND_FIRST - draw the box for the first time
126 SEND_UPDATE - redraw the updated box
127 otherwise - don't draw, just calculate.
128 Called with *widthp and *heightpas coordinates of
129 a test point, the routine reports the index of the character found
130 there in *indexp. *widthp and *heightp are set to the width and height
131 of the entire text in pixels.
134 /* LATER get this and sys_vgui to work together properly,
135 breaking up messages as needed. As of now, there's
136 a limit of 1950 characters, imposed by sys_vgui(). */
137 #define UPBUFSIZE 4000
140 /* Older (pre-8.3.4) TCL versions handle text selection differently; this
141 flag is set from the GUI if this happens. LATER take this out: early 2006? */
143 extern int sys_oldtclversion
;
145 static void rtext_senditup(t_rtext
*x
, int action
, int *widthp
, int *heightp
,
149 char tempbuf
[UPBUFSIZE
], *tp
= tempbuf
, *bp
= x
->x_buf
;
150 int outchars
, inchars
= x
->x_bufsize
, nlines
= 0, ncolumns
= 0,
152 int font
= glist_getfont(x
->x_glist
);
153 int fontwidth
= sys_fontwidth(font
), fontheight
= sys_fontheight(font
);
154 int findx
= (*widthp
+ (fontwidth
/2)) / fontwidth
,
155 findy
= *heightp
/ fontheight
;
156 int reportedindex
= 0;
157 t_canvas
*canvas
= glist_getcanvas(x
->x_glist
);
158 int widthspec
= x
->x_text
->te_width
;
159 int widthlimit
= (widthspec
? widthspec
: BOXWIDTH
);
162 int maxindex
= (inchars
> widthlimit
? widthlimit
: inchars
);
164 int foundit
= firstone(bp
, '\n', maxindex
);
167 if (inchars
> widthlimit
)
169 foundit
= lastone(bp
, ' ', maxindex
);
184 int actualx
= (findx
< 0 ? 0 :
185 (findx
> foundit
? foundit
: findx
));
186 *indexp
= (bp
- x
->x_buf
) + actualx
;
189 strncpy(tp
, bp
, foundit
);
191 bp
+= (foundit
+ eatchar
);
192 inchars
-= (foundit
+ eatchar
);
193 if (inchars
) *tp
++ = '\n';
194 if (foundit
> ncolumns
) ncolumns
= foundit
;
197 outchars
= tp
- tempbuf
;
198 if (outchars
> 1950) outchars
= 1950;
201 dispx
= text_xpix(x
->x_text
, x
->x_glist
);
202 dispy
= text_ypix(x
->x_text
, x
->x_glist
);
203 if (nlines
< 1) nlines
= 1;
208 tempbuf
[outchars
++] = ' ';
212 else ncolumns
= widthspec
;
213 pixwide
= ncolumns
* fontwidth
+ (LMARGIN
+ RMARGIN
);
214 pixhigh
= nlines
* fontheight
+ (TMARGIN
+ BMARGIN
);
216 if (action
== SEND_FIRST
)
217 sys_vgui("pdtk_text_new .x%x.c %s %f %f {%.*s} %d %s\n",
219 dispx
+ LMARGIN
, dispy
+ TMARGIN
,
220 outchars
, tempbuf
, sys_hostfontsize(font
),
221 (glist_isselected(x
->x_glist
,
222 &x
->x_glist
->gl_gobj
)? "blue" : "black"));
223 else if (action
== SEND_UPDATE
)
225 sys_vgui("pdtk_text_set .x%x.c %s {%.*s}\n",
226 canvas
, x
->x_tag
, outchars
, tempbuf
);
227 if (pixwide
!= x
->x_drawnwidth
|| pixhigh
!= x
->x_drawnheight
)
228 text_drawborder(x
->x_text
, x
->x_glist
, x
->x_tag
,
229 pixwide
, pixhigh
, 0);
232 if (x
->x_selend
> x
->x_selstart
)
234 sys_vgui(".x%x.c select from %s %d\n", canvas
,
235 x
->x_tag
, x
->x_selstart
);
236 sys_vgui(".x%x.c select to %s %d\n", canvas
,
237 x
->x_tag
, x
->x_selend
+ (sys_oldtclversion
? 0 : -1));
238 sys_vgui(".x%x.c focus \"\"\n", canvas
);
242 sys_vgui(".x%x.c select clear\n", canvas
);
243 sys_vgui(".x%x.c icursor %s %d\n", canvas
, x
->x_tag
,
245 sys_vgui(".x%x.c focus %s\n", canvas
, x
->x_tag
);
249 x
->x_drawnwidth
= pixwide
;
250 x
->x_drawnheight
= pixhigh
;
256 void rtext_retext(t_rtext
*x
)
258 int w
= 0, h
= 0, indx
;
259 t_text
*text
= x
->x_text
;
260 t_freebytes(x
->x_buf
, x
->x_bufsize
);
261 binbuf_gettext(text
->te_binbuf
, &x
->x_buf
, &x
->x_bufsize
);
262 /* special case: for number boxes, try to pare the number down
263 to the specified width of the box. */
264 if (text
->te_width
> 0 && text
->te_type
== T_ATOM
&&
265 x
->x_bufsize
> text
->te_width
)
267 t_atom
*atomp
= binbuf_getvec(text
->te_binbuf
);
268 int natom
= binbuf_getnatom(text
->te_binbuf
);
269 int bufsize
= x
->x_bufsize
;
270 if (natom
== 1 && atomp
->a_type
== A_FLOAT
)
272 /* try to reduce size by dropping decimal digits */
273 int wantreduce
= bufsize
- text
->te_width
;
274 char *decimal
= 0, *nextchar
, *ebuf
= x
->x_buf
+ bufsize
,
277 for (decimal
= x
->x_buf
; decimal
< ebuf
; decimal
++)
282 for (nextchar
= decimal
+ 1; nextchar
< ebuf
; nextchar
++)
283 if (*nextchar
< '0' || *nextchar
> '9')
285 if (nextchar
- decimal
- 1 < wantreduce
)
287 for (s1
= nextchar
- wantreduce
, s2
= s1
+ wantreduce
;
288 s2
< ebuf
; s1
++, s2
++)
290 t_resizebytes(x
->x_buf
, bufsize
, text
->te_width
);
291 bufsize
= text
->te_width
;
294 /* give up and bash it to "+" or "-" */
295 x
->x_buf
[0] = (atomp
->a_w
.w_float
< 0 ? '-' : '+');
296 t_resizebytes(x
->x_buf
, bufsize
, 1);
299 else if (bufsize
> text
->te_width
)
301 x
->x_buf
[text
->te_width
- 1] = '>';
302 t_resizebytes(x
->x_buf
, bufsize
, text
->te_width
);
303 bufsize
= text
->te_width
;
306 x
->x_bufsize
= bufsize
;
308 rtext_senditup(x
, SEND_UPDATE
, &w
, &h
, &indx
);
311 /* find the rtext that goes with a text item */
312 t_rtext
*glist_findrtext(t_glist
*gl
, t_text
*who
)
314 t_rtext
*x
= gl
->gl_editor
->e_rtext
;
315 while (x
&& x
->x_text
!= who
) x
= x
->x_next
;
316 if (!x
) bug("glist_findrtext");
320 int rtext_width(t_rtext
*x
)
322 int w
= 0, h
= 0, indx
;
323 rtext_senditup(x
, SEND_CHECK
, &w
, &h
, &indx
);
327 int rtext_height(t_rtext
*x
)
329 int w
= 0, h
= 0, indx
;
330 rtext_senditup(x
, SEND_CHECK
, &w
, &h
, &indx
);
334 void rtext_draw(t_rtext
*x
)
336 int w
= 0, h
= 0, indx
;
337 rtext_senditup(x
, SEND_FIRST
, &w
, &h
, &indx
);
340 void rtext_erase(t_rtext
*x
)
342 sys_vgui(".x%x.c delete %s\n", glist_getcanvas(x
->x_glist
), x
->x_tag
);
345 void rtext_displace(t_rtext
*x
, int dx
, int dy
)
347 sys_vgui(".x%x.c move %s %d %d\n", glist_getcanvas(x
->x_glist
),
351 void rtext_select(t_rtext
*x
, int state
)
353 t_glist
*glist
= x
->x_glist
;
354 t_canvas
*canvas
= glist_getcanvas(glist
);
355 sys_vgui(".x%x.c itemconfigure %s -fill %s\n", canvas
,
356 x
->x_tag
, (state
? "blue" : "black"));
357 canvas_editing
= canvas
;
360 void rtext_activate(t_rtext
*x
, int state
)
362 int w
= 0, h
= 0, indx
;
363 t_glist
*glist
= x
->x_glist
;
364 t_canvas
*canvas
= glist_getcanvas(glist
);
367 sys_vgui(".x%x.c focus %s\n", canvas
, x
->x_tag
);
368 glist
->gl_editor
->e_textedfor
= x
;
369 glist
->gl_editor
->e_textdirty
= 0;
370 x
->x_dragfrom
= x
->x_selstart
= 0;
371 x
->x_selend
= x
->x_bufsize
;
376 sys_vgui("selection clear .x%x.c\n", canvas
);
377 sys_vgui(".x%x.c focus \"\"\n", canvas
);
378 if (glist
->gl_editor
->e_textedfor
== x
)
379 glist
->gl_editor
->e_textedfor
= 0;
382 rtext_senditup(x
, SEND_UPDATE
, &w
, &h
, &indx
);
385 void rtext_key(t_rtext
*x
, int keynum
, t_symbol
*keysym
)
387 int w
= 0, h
= 0, indx
, i
, newsize
, ndel
;
392 if (n
== '\r') n
= '\n';
393 if (n
== '\b') /* backspace */
395 /* LATER delete the box if all text is selected...
396 this causes reentrancy problems now. */
397 /* if ((!x->x_selstart) && (x->x_selend == x->x_bufsize))
401 if (x
->x_selstart
&& (x
->x_selstart
== x
->x_selend
))
404 else if (n
== 127) /* delete */
406 if (x
->x_selend
< x
->x_bufsize
&& (x
->x_selstart
== x
->x_selend
))
410 ndel
= x
->x_selend
- x
->x_selstart
;
411 for (i
= x
->x_selend
; i
< x
->x_bufsize
; i
++)
412 x
->x_buf
[i
- ndel
] = x
->x_buf
[i
];
413 newsize
= x
->x_bufsize
- ndel
;
414 x
->x_buf
= resizebytes(x
->x_buf
, x
->x_bufsize
, newsize
);
415 x
->x_bufsize
= newsize
;
417 if (n
== '\n' || isprint(n
))
419 newsize
= x
->x_bufsize
+1;
420 x
->x_buf
= resizebytes(x
->x_buf
, x
->x_bufsize
, newsize
);
421 for (i
= x
->x_bufsize
; i
> x
->x_selstart
; i
--)
422 x
->x_buf
[i
] = x
->x_buf
[i
-1];
423 x
->x_buf
[x
->x_selstart
] = n
;
424 x
->x_bufsize
= newsize
;
425 x
->x_selstart
= x
->x_selstart
+ 1;
427 x
->x_selend
= x
->x_selstart
;
428 x
->x_glist
->gl_editor
->e_textdirty
= 1;
430 else if (!strcmp(keysym
->s_name
, "Right"))
432 if (x
->x_selend
== x
->x_selstart
&& x
->x_selstart
< x
->x_bufsize
)
433 x
->x_selend
= x
->x_selstart
= x
->x_selstart
+ 1;
435 x
->x_selstart
= x
->x_selend
;
437 else if (!strcmp(keysym
->s_name
, "Left"))
439 if (x
->x_selend
== x
->x_selstart
&& x
->x_selstart
> 0)
440 x
->x_selend
= x
->x_selstart
= x
->x_selstart
- 1;
442 x
->x_selend
= x
->x_selstart
;
444 /* this should be improved... life's too short */
445 else if (!strcmp(keysym
->s_name
, "Up"))
449 while (x
->x_selstart
> 0 && x
->x_buf
[x
->x_selstart
] != '\n')
451 x
->x_selend
= x
->x_selstart
;
453 else if (!strcmp(keysym
->s_name
, "Down"))
455 while (x
->x_selend
< x
->x_bufsize
&&
456 x
->x_buf
[x
->x_selend
] != '\n')
458 if (x
->x_selend
< x
->x_bufsize
)
460 x
->x_selstart
= x
->x_selend
;
462 rtext_senditup(x
, SEND_UPDATE
, &w
, &h
, &indx
);
465 void rtext_mouse(t_rtext
*x
, int xval
, int yval
, int flag
)
467 int w
= xval
, h
= yval
, indx
;
468 rtext_senditup(x
, SEND_CHECK
, &w
, &h
, &indx
);
469 if (flag
== RTEXT_DOWN
)
471 x
->x_dragfrom
= x
->x_selstart
= x
->x_selend
= indx
;
473 else if (flag
== RTEXT_SHIFT
)
475 if (indx
* 2 > x
->x_selstart
+ x
->x_selend
)
476 x
->x_dragfrom
= x
->x_selstart
, x
->x_selend
= indx
;
478 x
->x_dragfrom
= x
->x_selend
, x
->x_selstart
= indx
;
480 else if (flag
== RTEXT_DRAG
)
482 x
->x_selstart
= (x
->x_dragfrom
< indx
? x
->x_dragfrom
: indx
);
483 x
->x_selend
= (x
->x_dragfrom
> indx
? x
->x_dragfrom
: indx
);
485 rtext_senditup(x
, SEND_UPDATE
, &w
, &h
, &indx
);
487 /* Copyright (c) 1997-1999 Miller Puckette.
488 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
489 * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
491 /* changes by Thomas Musil IEM KUG Graz Austria 2001 */
492 /* have to insert gui-objects into editor-list */
493 /* all changes are labeled with iemlib */
501 #include "g_canvas.h"
510 #define SEND_UPDATE 2
527 struct _rtext
*x_next
;
530 t_rtext
*rtext_new(t_glist
*glist
, t_text
*who
)
532 t_rtext
*x
= (t_rtext
*)getbytes(sizeof *x
);
533 int w
= 0, h
= 0, indx
;
537 x
->x_next
= glist
->gl_editor
->e_rtext
;
538 x
->x_selstart
= x
->x_selend
= x
->x_active
=
539 x
->x_drawnwidth
= x
->x_drawnheight
= 0;
540 binbuf_gettext(who
->te_binbuf
, &x
->x_buf
, &x
->x_bufsize
);
541 glist
->gl_editor
->e_rtext
= x
;
542 sprintf(x
->x_tag
, ".x%x.t%x", (t_int
)glist_getcanvas(x
->x_glist
),
547 static t_rtext
*rtext_entered
;
549 void rtext_free(t_rtext
*x
)
551 if (x
->x_glist
->gl_editor
->e_textedfor
== x
)
552 x
->x_glist
->gl_editor
->e_textedfor
= 0;
553 if (x
->x_glist
->gl_editor
->e_rtext
== x
)
554 x
->x_glist
->gl_editor
->e_rtext
= x
->x_next
;
558 for (e2
= x
->x_glist
->gl_editor
->e_rtext
; e2
; e2
= e2
->x_next
)
561 e2
->x_next
= x
->x_next
;
565 if (rtext_entered
== x
) rtext_entered
= 0;
566 freebytes(x
->x_buf
, x
->x_bufsize
);
567 freebytes(x
, sizeof *x
);
570 char *rtext_gettag(t_rtext
*x
)
575 void rtext_gettext(t_rtext
*x
, char **buf
, int *bufsize
)
578 *bufsize
= x
->x_bufsize
;
582 /* LATER deal with tcl-significant characters */
584 static int firstone(char *s
, int c
, int n
)
590 if (*s
== c
) return (i
);
597 static int lastone(char *s
, int c
, int n
)
604 if (*s2
== c
) return (n
);
609 /* the following routine computes line breaks and carries out
610 some action which could be:
611 SEND_FIRST - draw the box for the first time
612 SEND_UPDATE - redraw the updated box
613 otherwise - don't draw, just calculate.
614 Called with *widthp and *heightpas coordinates of
615 a test point, the routine reports the index of the character found
616 there in *indexp. *widthp and *heightp are set to the width and height
617 of the entire text in pixels.
620 /* LATER get this and sys_vgui to work together properly,
621 breaking up messages as needed. As of now, there's
622 a limit of 1950 characters, imposed by sys_vgui(). */
623 #define UPBUFSIZE 4000
626 /* Older (pre-8.3.4) TCL versions handle text selection differently; this
627 flag is set from the GUI if this happens. LATER take this out: early 2006? */
629 extern int sys_oldtclversion
;
631 static void rtext_senditup(t_rtext
*x
, int action
, int *widthp
, int *heightp
,
635 char tempbuf
[UPBUFSIZE
], *tp
= tempbuf
, *bp
= x
->x_buf
;
636 int outchars
, inchars
= x
->x_bufsize
, nlines
= 0, ncolumns
= 0,
638 int font
= glist_getfont(x
->x_glist
);
639 int fontwidth
= sys_fontwidth(font
), fontheight
= sys_fontheight(font
);
640 int findx
= (*widthp
+ (fontwidth
/2)) / fontwidth
,
641 findy
= *heightp
/ fontheight
;
642 int reportedindex
= 0;
643 t_canvas
*canvas
= glist_getcanvas(x
->x_glist
);
644 int widthspec
= x
->x_text
->te_width
;
645 int widthlimit
= (widthspec
? widthspec
: BOXWIDTH
);
648 int maxindex
= (inchars
> widthlimit
? widthlimit
: inchars
);
650 int foundit
= firstone(bp
, '\n', maxindex
);
653 if (inchars
> widthlimit
)
655 foundit
= lastone(bp
, ' ', maxindex
);
670 int actualx
= (findx
< 0 ? 0 :
671 (findx
> foundit
? foundit
: findx
));
672 *indexp
= (bp
- x
->x_buf
) + actualx
;
675 strncpy(tp
, bp
, foundit
);
677 bp
+= (foundit
+ eatchar
);
678 inchars
-= (foundit
+ eatchar
);
679 if (inchars
) *tp
++ = '\n';
680 if (foundit
> ncolumns
) ncolumns
= foundit
;
683 outchars
= tp
- tempbuf
;
684 if (outchars
> 1950) outchars
= 1950;
687 dispx
= text_xpix(x
->x_text
, x
->x_glist
);
688 dispy
= text_ypix(x
->x_text
, x
->x_glist
);
689 if (nlines
< 1) nlines
= 1;
694 tempbuf
[outchars
++] = ' ';
698 else ncolumns
= widthspec
;
699 pixwide
= ncolumns
* fontwidth
+ (LMARGIN
+ RMARGIN
);
700 pixhigh
= nlines
* fontheight
+ (TMARGIN
+ BMARGIN
);
702 if (action
== SEND_FIRST
)
703 sys_vgui("pdtk_text_new .x%x.c %s %f %f {%.*s} %d %s\n",
705 dispx
+ LMARGIN
, dispy
+ TMARGIN
,
706 outchars
, tempbuf
, sys_hostfontsize(font
),
707 (glist_isselected(x
->x_glist
,
708 &x
->x_glist
->gl_gobj
)? "blue" : "black"));
709 else if (action
== SEND_UPDATE
)
711 sys_vgui("pdtk_text_set .x%x.c %s {%.*s}\n",
712 canvas
, x
->x_tag
, outchars
, tempbuf
);
713 if (pixwide
!= x
->x_drawnwidth
|| pixhigh
!= x
->x_drawnheight
)
714 text_drawborder(x
->x_text
, x
->x_glist
, x
->x_tag
,
715 pixwide
, pixhigh
, 0);
718 if (x
->x_selend
> x
->x_selstart
)
720 sys_vgui(".x%x.c select from %s %d\n", canvas
,
721 x
->x_tag
, x
->x_selstart
);
722 sys_vgui(".x%x.c select to %s %d\n", canvas
,
723 x
->x_tag
, x
->x_selend
+ (sys_oldtclversion
? 0 : -1));
724 sys_vgui(".x%x.c focus \"\"\n", canvas
);
728 sys_vgui(".x%x.c select clear\n", canvas
);
729 sys_vgui(".x%x.c icursor %s %d\n", canvas
, x
->x_tag
,
731 sys_vgui(".x%x.c focus %s\n", canvas
, x
->x_tag
);
735 x
->x_drawnwidth
= pixwide
;
736 x
->x_drawnheight
= pixhigh
;
742 void rtext_retext(t_rtext
*x
)
744 int w
= 0, h
= 0, indx
;
745 t_text
*text
= x
->x_text
;
746 t_freebytes(x
->x_buf
, x
->x_bufsize
);
747 binbuf_gettext(text
->te_binbuf
, &x
->x_buf
, &x
->x_bufsize
);
748 /* special case: for number boxes, try to pare the number down
749 to the specified width of the box. */
750 if (text
->te_width
> 0 && text
->te_type
== T_ATOM
&&
751 x
->x_bufsize
> text
->te_width
)
753 t_atom
*atomp
= binbuf_getvec(text
->te_binbuf
);
754 int natom
= binbuf_getnatom(text
->te_binbuf
);
755 int bufsize
= x
->x_bufsize
;
756 if (natom
== 1 && atomp
->a_type
== A_FLOAT
)
758 /* try to reduce size by dropping decimal digits */
759 int wantreduce
= bufsize
- text
->te_width
;
760 char *decimal
= 0, *nextchar
, *ebuf
= x
->x_buf
+ bufsize
,
763 for (decimal
= x
->x_buf
; decimal
< ebuf
; decimal
++)
768 for (nextchar
= decimal
+ 1; nextchar
< ebuf
; nextchar
++)
769 if (*nextchar
< '0' || *nextchar
> '9')
771 if (nextchar
- decimal
- 1 < wantreduce
)
773 for (s1
= nextchar
- wantreduce
, s2
= s1
+ wantreduce
;
774 s2
< ebuf
; s1
++, s2
++)
776 t_resizebytes(x
->x_buf
, bufsize
, text
->te_width
);
777 bufsize
= text
->te_width
;
780 /* give up and bash it to "+" or "-" */
781 x
->x_buf
[0] = (atomp
->a_w
.w_float
< 0 ? '-' : '+');
782 t_resizebytes(x
->x_buf
, bufsize
, 1);
785 else if (bufsize
> text
->te_width
)
787 x
->x_buf
[text
->te_width
- 1] = '>';
788 t_resizebytes(x
->x_buf
, bufsize
, text
->te_width
);
789 bufsize
= text
->te_width
;
792 x
->x_bufsize
= bufsize
;
794 rtext_senditup(x
, SEND_UPDATE
, &w
, &h
, &indx
);
797 /* find the rtext that goes with a text item */
798 t_rtext
*glist_findrtext(t_glist
*gl
, t_text
*who
)
800 t_rtext
*x
= gl
->gl_editor
->e_rtext
;
801 while (x
&& x
->x_text
!= who
) x
= x
->x_next
;
802 if (!x
) bug("glist_findrtext");
806 int rtext_width(t_rtext
*x
)
808 int w
= 0, h
= 0, indx
;
809 rtext_senditup(x
, SEND_CHECK
, &w
, &h
, &indx
);
813 int rtext_height(t_rtext
*x
)
815 int w
= 0, h
= 0, indx
;
816 rtext_senditup(x
, SEND_CHECK
, &w
, &h
, &indx
);
820 void rtext_draw(t_rtext
*x
)
822 int w
= 0, h
= 0, indx
;
823 rtext_senditup(x
, SEND_FIRST
, &w
, &h
, &indx
);
826 void rtext_erase(t_rtext
*x
)
828 sys_vgui(".x%x.c delete %s\n", glist_getcanvas(x
->x_glist
), x
->x_tag
);
831 void rtext_displace(t_rtext
*x
, int dx
, int dy
)
833 sys_vgui(".x%x.c move %s %d %d\n", glist_getcanvas(x
->x_glist
),
837 void rtext_select(t_rtext
*x
, int state
)
839 t_glist
*glist
= x
->x_glist
;
840 t_canvas
*canvas
= glist_getcanvas(glist
);
841 sys_vgui(".x%x.c itemconfigure %s -fill %s\n", canvas
,
842 x
->x_tag
, (state
? "blue" : "black"));
843 canvas_editing
= canvas
;
846 void rtext_activate(t_rtext
*x
, int state
)
848 int w
= 0, h
= 0, indx
;
849 t_glist
*glist
= x
->x_glist
;
850 t_canvas
*canvas
= glist_getcanvas(glist
);
853 sys_vgui(".x%x.c focus %s\n", canvas
, x
->x_tag
);
854 glist
->gl_editor
->e_textedfor
= x
;
855 glist
->gl_editor
->e_textdirty
= 0;
856 x
->x_dragfrom
= x
->x_selstart
= 0;
857 x
->x_selend
= x
->x_bufsize
;
862 sys_vgui("selection clear .x%x.c\n", canvas
);
863 sys_vgui(".x%x.c focus \"\"\n", canvas
);
864 if (glist
->gl_editor
->e_textedfor
== x
)
865 glist
->gl_editor
->e_textedfor
= 0;
868 rtext_senditup(x
, SEND_UPDATE
, &w
, &h
, &indx
);
871 void rtext_key(t_rtext
*x
, int keynum
, t_symbol
*keysym
)
873 int w
= 0, h
= 0, indx
, i
, newsize
, ndel
;
878 if (n
== '\r') n
= '\n';
879 if (n
== '\b') /* backspace */
881 /* LATER delete the box if all text is selected...
882 this causes reentrancy problems now. */
883 /* if ((!x->x_selstart) && (x->x_selend == x->x_bufsize))
887 if (x
->x_selstart
&& (x
->x_selstart
== x
->x_selend
))
890 else if (n
== 127) /* delete */
892 if (x
->x_selend
< x
->x_bufsize
&& (x
->x_selstart
== x
->x_selend
))
896 ndel
= x
->x_selend
- x
->x_selstart
;
897 for (i
= x
->x_selend
; i
< x
->x_bufsize
; i
++)
898 x
->x_buf
[i
- ndel
] = x
->x_buf
[i
];
899 newsize
= x
->x_bufsize
- ndel
;
900 x
->x_buf
= resizebytes(x
->x_buf
, x
->x_bufsize
, newsize
);
901 x
->x_bufsize
= newsize
;
903 if (n
== '\n' || isprint(n
))
905 newsize
= x
->x_bufsize
+1;
906 x
->x_buf
= resizebytes(x
->x_buf
, x
->x_bufsize
, newsize
);
907 for (i
= x
->x_bufsize
; i
> x
->x_selstart
; i
--)
908 x
->x_buf
[i
] = x
->x_buf
[i
-1];
909 x
->x_buf
[x
->x_selstart
] = n
;
910 x
->x_bufsize
= newsize
;
911 x
->x_selstart
= x
->x_selstart
+ 1;
913 x
->x_selend
= x
->x_selstart
;
914 x
->x_glist
->gl_editor
->e_textdirty
= 1;
916 else if (!strcmp(keysym
->s_name
, "Right"))
918 if (x
->x_selend
== x
->x_selstart
&& x
->x_selstart
< x
->x_bufsize
)
919 x
->x_selend
= x
->x_selstart
= x
->x_selstart
+ 1;
921 x
->x_selstart
= x
->x_selend
;
923 else if (!strcmp(keysym
->s_name
, "Left"))
925 if (x
->x_selend
== x
->x_selstart
&& x
->x_selstart
> 0)
926 x
->x_selend
= x
->x_selstart
= x
->x_selstart
- 1;
928 x
->x_selend
= x
->x_selstart
;
930 /* this should be improved... life's too short */
931 else if (!strcmp(keysym
->s_name
, "Up"))
935 while (x
->x_selstart
> 0 && x
->x_buf
[x
->x_selstart
] != '\n')
937 x
->x_selend
= x
->x_selstart
;
939 else if (!strcmp(keysym
->s_name
, "Down"))
941 while (x
->x_selend
< x
->x_bufsize
&&
942 x
->x_buf
[x
->x_selend
] != '\n')
944 if (x
->x_selend
< x
->x_bufsize
)
946 x
->x_selstart
= x
->x_selend
;
948 rtext_senditup(x
, SEND_UPDATE
, &w
, &h
, &indx
);
951 void rtext_mouse(t_rtext
*x
, int xval
, int yval
, int flag
)
953 int w
= xval
, h
= yval
, indx
;
954 rtext_senditup(x
, SEND_CHECK
, &w
, &h
, &indx
);
955 if (flag
== RTEXT_DOWN
)
957 x
->x_dragfrom
= x
->x_selstart
= x
->x_selend
= indx
;
959 else if (flag
== RTEXT_SHIFT
)
961 if (indx
* 2 > x
->x_selstart
+ x
->x_selend
)
962 x
->x_dragfrom
= x
->x_selstart
, x
->x_selend
= indx
;
964 x
->x_dragfrom
= x
->x_selend
, x
->x_selstart
= indx
;
966 else if (flag
== RTEXT_DRAG
)
968 x
->x_selstart
= (x
->x_dragfrom
< indx
? x
->x_dragfrom
: indx
);
969 x
->x_selend
= (x
->x_dragfrom
> indx
? x
->x_dragfrom
: indx
);
971 rtext_senditup(x
, SEND_UPDATE
, &w
, &h
, &indx
);