summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/g_rtext.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/g_rtext.c')
-rw-r--r--apps/plugins/pdbox/PDa/src/g_rtext.c485
1 files changed, 0 insertions, 485 deletions
diff --git a/apps/plugins/pdbox/PDa/src/g_rtext.c b/apps/plugins/pdbox/PDa/src/g_rtext.c
index 8ffc8f415b..05c31a9ea7 100644
--- a/apps/plugins/pdbox/PDa/src/g_rtext.c
+++ b/apps/plugins/pdbox/PDa/src/g_rtext.c
@@ -484,489 +484,4 @@ void rtext_mouse(t_rtext *x, int xval, int yval, int flag)
484 } 484 }
485 rtext_senditup(x, SEND_UPDATE, &w, &h, &indx); 485 rtext_senditup(x, SEND_UPDATE, &w, &h, &indx);
486} 486}
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. */
490
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 */
494
495#include <stdlib.h>
496#include <string.h>
497#include <stdio.h>
498#include <ctype.h>
499#include "m_pd.h"
500#include "s_stuff.h"
501#include "g_canvas.h"
502#include "t_tk.h"
503
504#define LMARGIN 1
505#define RMARGIN 1
506#define TMARGIN 2
507#define BMARGIN 2
508
509#define SEND_FIRST 1
510#define SEND_UPDATE 2
511#define SEND_CHECK 0
512
513struct _rtext
514{
515 char *x_buf;
516 int x_bufsize;
517 int x_selstart;
518 int x_selend;
519 int x_active;
520 int x_dragfrom;
521 int x_height;
522 int x_drawnwidth;
523 int x_drawnheight;
524 t_text *x_text;
525 t_glist *x_glist;
526 char x_tag[50];
527 struct _rtext *x_next;
528};
529
530t_rtext *rtext_new(t_glist *glist, t_text *who)
531{
532 t_rtext *x = (t_rtext *)getbytes(sizeof *x);
533 int w = 0, h = 0, indx;
534 x->x_height = -1;
535 x->x_text = who;
536 x->x_glist = glist;
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),
543 (t_int)x);
544 return (x);
545}
546
547static t_rtext *rtext_entered;
548 487
549void rtext_free(t_rtext *x)
550{
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;
555 else
556 {
557 t_rtext *e2;
558 for (e2 = x->x_glist->gl_editor->e_rtext; e2; e2 = e2->x_next)
559 if (e2->x_next == x)
560 {
561 e2->x_next = x->x_next;
562 break;
563 }
564 }
565 if (rtext_entered == x) rtext_entered = 0;
566 freebytes(x->x_buf, x->x_bufsize);
567 freebytes(x, sizeof *x);
568}
569
570char *rtext_gettag(t_rtext *x)
571{
572 return (x->x_tag);
573}
574
575void rtext_gettext(t_rtext *x, char **buf, int *bufsize)
576{
577 *buf = x->x_buf;
578 *bufsize = x->x_bufsize;
579}
580
581
582/* LATER deal with tcl-significant characters */
583
584static int firstone(char *s, int c, int n)
585{
586 char *s2 = s + n;
587 int i = 0;
588 while (s != s2)
589 {
590 if (*s == c) return (i);
591 i++;
592 s++;
593 }
594 return (-1);
595}
596
597static int lastone(char *s, int c, int n)
598{
599 char *s2 = s + n;
600 while (s2 != s)
601 {
602 s2--;
603 n--;
604 if (*s2 == c) return (n);
605 }
606 return (-1);
607}
608
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.
618 */
619
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
624#define BOXWIDTH 60
625
626/* Older (pre-8.3.4) TCL versions handle text selection differently; this
627flag is set from the GUI if this happens. LATER take this out: early 2006? */
628
629extern int sys_oldtclversion;
630
631static void rtext_senditup(t_rtext *x, int action, int *widthp, int *heightp,
632 int *indexp)
633{
634 float dispx, dispy;
635 char tempbuf[UPBUFSIZE], *tp = tempbuf, *bp = x->x_buf;
636 int outchars, inchars = x->x_bufsize, nlines = 0, ncolumns = 0,
637 pixwide, pixhigh;
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);
646 while (inchars)
647 {
648 int maxindex = (inchars > widthlimit ? widthlimit : inchars);
649 int eatchar = 1;
650 int foundit = firstone(bp, '\n', maxindex);
651 if (foundit < 0)
652 {
653 if (inchars > widthlimit)
654 {
655 foundit = lastone(bp, ' ', maxindex);
656 if (foundit < 0)
657 {
658 foundit = maxindex;
659 eatchar = 0;
660 }
661 }
662 else
663 {
664 foundit = inchars;
665 eatchar = 0;
666 }
667 }
668 if (nlines == findy)
669 {
670 int actualx = (findx < 0 ? 0 :
671 (findx > foundit ? foundit : findx));
672 *indexp = (bp - x->x_buf) + actualx;
673 reportedindex = 1;
674 }
675 strncpy(tp, bp, foundit);
676 tp += foundit;
677 bp += (foundit + eatchar);
678 inchars -= (foundit + eatchar);
679 if (inchars) *tp++ = '\n';
680 if (foundit > ncolumns) ncolumns = foundit;
681 nlines++;
682 }
683 outchars = tp - tempbuf;
684 if (outchars > 1950) outchars = 1950;
685 if (!reportedindex)
686 *indexp = outchars;
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;
690 if (!widthspec)
691 {
692 while (ncolumns < 3)
693 {
694 tempbuf[outchars++] = ' ';
695 ncolumns++;
696 }
697 }
698 else ncolumns = widthspec;
699 pixwide = ncolumns * fontwidth + (LMARGIN + RMARGIN);
700 pixhigh = nlines * fontheight + (TMARGIN + BMARGIN);
701
702 if (action == SEND_FIRST)
703 sys_vgui("pdtk_text_new .x%x.c %s %f %f {%.*s} %d %s\n",
704 canvas, x->x_tag,
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)
710 {
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);
716 if (x->x_active)
717 {
718 if (x->x_selend > x->x_selstart)
719 {
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);
725 }
726 else
727 {
728 sys_vgui(".x%x.c select clear\n", canvas);
729 sys_vgui(".x%x.c icursor %s %d\n", canvas, x->x_tag,
730 x->x_selstart);
731 sys_vgui(".x%x.c focus %s\n", canvas, x->x_tag);
732 }
733 }
734 }
735 x->x_drawnwidth = pixwide;
736 x->x_drawnheight = pixhigh;
737
738 *widthp = pixwide;
739 *heightp = pixhigh;
740}
741
742void rtext_retext(t_rtext *x)
743{
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)
752 {
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)
757 {
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,
761 *s1, *s2;
762 int ndecimals;
763 for (decimal = x->x_buf; decimal < ebuf; decimal++)
764 if (*decimal == '.')
765 break;
766 if (decimal >= ebuf)
767 goto giveup;
768 for (nextchar = decimal + 1; nextchar < ebuf; nextchar++)
769 if (*nextchar < '0' || *nextchar > '9')
770 break;
771 if (nextchar - decimal - 1 < wantreduce)
772 goto giveup;
773 for (s1 = nextchar - wantreduce, s2 = s1 + wantreduce;
774 s2 < ebuf; s1++, s2++)
775 *s1 = *s2;
776 t_resizebytes(x->x_buf, bufsize, text->te_width);
777 bufsize = text->te_width;
778 goto done;
779 giveup:
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);
783 bufsize = 1;
784 }
785 else if (bufsize > text->te_width)
786 {
787 x->x_buf[text->te_width - 1] = '>';
788 t_resizebytes(x->x_buf, bufsize, text->te_width);
789 bufsize = text->te_width;
790 }
791 done:
792 x->x_bufsize = bufsize;
793 }
794 rtext_senditup(x, SEND_UPDATE, &w, &h, &indx);
795}
796
797/* find the rtext that goes with a text item */
798t_rtext *glist_findrtext(t_glist *gl, t_text *who)
799{
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");
803 return (x);
804}
805
806int rtext_width(t_rtext *x)
807{
808 int w = 0, h = 0, indx;
809 rtext_senditup(x, SEND_CHECK, &w, &h, &indx);
810 return (w);
811}
812
813int rtext_height(t_rtext *x)
814{
815 int w = 0, h = 0, indx;
816 rtext_senditup(x, SEND_CHECK, &w, &h, &indx);
817 return (h);
818}
819
820void rtext_draw(t_rtext *x)
821{
822 int w = 0, h = 0, indx;
823 rtext_senditup(x, SEND_FIRST, &w, &h, &indx);
824}
825
826void rtext_erase(t_rtext *x)
827{
828 sys_vgui(".x%x.c delete %s\n", glist_getcanvas(x->x_glist), x->x_tag);
829}
830
831void rtext_displace(t_rtext *x, int dx, int dy)
832{
833 sys_vgui(".x%x.c move %s %d %d\n", glist_getcanvas(x->x_glist),
834 x->x_tag, dx, dy);
835}
836
837void rtext_select(t_rtext *x, int state)
838{
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;
844}
845
846void rtext_activate(t_rtext *x, int state)
847{
848 int w = 0, h = 0, indx;
849 t_glist *glist = x->x_glist;
850 t_canvas *canvas = glist_getcanvas(glist);
851 if (state)
852 {
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;
858 x->x_active = 1;
859 }
860 else
861 {
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;
866 x->x_active = 0;
867 }
868 rtext_senditup(x, SEND_UPDATE, &w, &h, &indx);
869}
870
871void rtext_key(t_rtext *x, int keynum, t_symbol *keysym)
872{
873 int w = 0, h = 0, indx, i, newsize, ndel;
874 char *s1, *s2;
875 if (keynum)
876 {
877 int n = keynum;
878 if (n == '\r') n = '\n';
879 if (n == '\b') /* backspace */
880 {
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))
884 {
885 ....
886 } */
887 if (x->x_selstart && (x->x_selstart == x->x_selend))
888 x->x_selstart--;
889 }
890 else if (n == 127) /* delete */
891 {
892 if (x->x_selend < x->x_bufsize && (x->x_selstart == x->x_selend))
893 x->x_selend++;
894 }
895
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;
902
903 if (n == '\n' || isprint(n))
904 {
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;
912 }
913 x->x_selend = x->x_selstart;
914 x->x_glist->gl_editor->e_textdirty = 1;
915 }
916 else if (!strcmp(keysym->s_name, "Right"))
917 {
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;
920 else
921 x->x_selstart = x->x_selend;
922 }
923 else if (!strcmp(keysym->s_name, "Left"))
924 {
925 if (x->x_selend == x->x_selstart && x->x_selstart > 0)
926 x->x_selend = x->x_selstart = x->x_selstart - 1;
927 else
928 x->x_selend = x->x_selstart;
929 }
930 /* this should be improved... life's too short */
931 else if (!strcmp(keysym->s_name, "Up"))
932 {
933 if (x->x_selstart)
934 x->x_selstart--;
935 while (x->x_selstart > 0 && x->x_buf[x->x_selstart] != '\n')
936 x->x_selstart--;
937 x->x_selend = x->x_selstart;
938 }
939 else if (!strcmp(keysym->s_name, "Down"))
940 {
941 while (x->x_selend < x->x_bufsize &&
942 x->x_buf[x->x_selend] != '\n')
943 x->x_selend++;
944 if (x->x_selend < x->x_bufsize)
945 x->x_selend++;
946 x->x_selstart = x->x_selend;
947 }
948 rtext_senditup(x, SEND_UPDATE, &w, &h, &indx);
949}
950
951void rtext_mouse(t_rtext *x, int xval, int yval, int flag)
952{
953 int w = xval, h = yval, indx;
954 rtext_senditup(x, SEND_CHECK, &w, &h, &indx);
955 if (flag == RTEXT_DOWN)
956 {
957 x->x_dragfrom = x->x_selstart = x->x_selend = indx;
958 }
959 else if (flag == RTEXT_SHIFT)
960 {
961 if (indx * 2 > x->x_selstart + x->x_selend)
962 x->x_dragfrom = x->x_selstart, x->x_selend = indx;
963 else
964 x->x_dragfrom = x->x_selend, x->x_selstart = indx;
965 }
966 else if (flag == RTEXT_DRAG)
967 {
968 x->x_selstart = (x->x_dragfrom < indx ? x->x_dragfrom : indx);
969 x->x_selend = (x->x_dragfrom > indx ? x->x_dragfrom : indx);
970 }
971 rtext_senditup(x, SEND_UPDATE, &w, &h, &indx);
972}