3 * void plescroll(Panel *p, int top);
4 * move the given character position onto the top line
5 * void plegetsel(Panel *p, int *sel0, int *sel1);
6 * read the selection back
7 * int plelen(Panel *p);
8 * read the length of the text back
9 * Rune *pleget(Panel *p);
10 * get a pointer to the text
11 * void plesel(Panel *p, int sel0, int sel1);
12 * set the selection -- adjusts hiliting
13 * void plepaste(Panel *p, Rune *text, int ntext);
14 * replace the selection with the given text
24 typedef struct Edit Edit;
33 void pl_drawedit(Panel *p){
38 ep->t=twnew(p->b, font, ep->text, ep->ntext);
40 fprint(2, "pl_drawedit: can't allocate\n");
45 twreshape(ep->t, p->r);
46 twhilite(ep->t, ep->sel0, ep->sel1, 1);
48 if(sb && sb->setscrollbar)
49 sb->setscrollbar(sb, ep->t->top, ep->t->bot, ep->t->etext-ep->t->text);
52 char *pl_snarfedit(Panel *p){
57 plegetsel(p, &s0, &s1);
60 return smprint("%.*S", s1-s0, t+s0);
62 void pl_pasteedit(Panel *p, char *s){
64 if(t=runesmprint("%s", s)){
65 plepaste(p, t, runestrlen(t));
71 * Should do double-clicks:
72 * If ep->sel0==ep->sel1 on entry and the
73 * call to twselect returns the same selection, then
74 * expand selections (| marks possible selection points, ... is expanded selection)
75 * <|...|> <> must nest
76 * (|...|) () must nest
77 * [|...|] [] must nest
78 * {|...|} {} must nest
81 * \n|...|\n either newline may be the corresponding end of text
82 * include the trailing newline in the selection
83 * ...|I... I and ... are characters satisfying pl_idchar(I)
86 int pl_hitedit(Panel *p, Mouse *m){
92 twhilite(ep->t, ep->sel0, ep->sel1, 0);
96 if((m->buttons&7)==3){
98 plepaste(p, 0, 0); /* cut */
100 else if((m->buttons&7)==5)
107 void pl_scrolledit(Panel *p, int dir, int buttons, int num, int den){
112 if(dir!=VERT) return;
119 case 1: /* top line moves to mouse position */
120 nline=(t->r.max.y-t->r.min.y)/t->hgt*num/den;
122 while(index!=0 && nline!=0)
123 if(t->text[--index]=='\n') --nline;
125 case 2: /* absolute */
126 index=(t->etext-t->text)*num/den;
128 case 4: /* mouse points at new top line */
130 Pt(t->r.min.x, t->r.min.y+(t->r.max.y-t->r.min.y)*num/den));
133 while(index!=0 && t->text[index-1]!='\n') --index;
135 twhilite(ep->t, ep->sel0, ep->sel1, 0);
138 twhilite(ep->t, ep->sel0, ep->sel1, 1);
140 if(sb && sb->setscrollbar)
141 sb->setscrollbar(sb, t->top, t->bot, t->etext-t->text);
144 void pl_typeedit(Panel *p, Rune c){
152 twhilite(t, ep->sel0, ep->sel1, 0);
156 plepaste(p, 0, 0); /* cut */
158 case Kdel: /* clear */
161 plepaste(p, 0, 0); /* cut */
163 case Kbs: /* ^H: erase character */
164 if(ep->sel0!=0) --ep->sel0;
165 twreplace(t, ep->sel0, ep->sel1, 0, 0);
167 case Knack: /* ^U: erase line */
168 while(ep->sel0!=0 && t->text[ep->sel0-1]!='\n') --ep->sel0;
169 twreplace(t, ep->sel0, ep->sel1, 0, 0);
171 case Ketb: /* ^W: erase word */
172 while(ep->sel0!=0 && !pl_idchar(t->text[ep->sel0-1])) --ep->sel0;
173 while(ep->sel0!=0 && pl_idchar(t->text[ep->sel0-1])) --ep->sel0;
174 twreplace(t, ep->sel0, ep->sel1, 0, 0);
177 if((c & 0xFF00) == KF || (c & 0xFF00) == Spec)
179 twreplace(t, ep->sel0, ep->sel1, &c, 1);
185 * Scroll up until ep->sel0 is above t->bot.
190 if(ep->sel0<=bot) break;
191 twscroll(t, twpt2rune(t, Pt(t->r.min.x, t->r.min.y+font->height)));
196 if(sb && sb->setscrollbar)
197 sb->setscrollbar(sb, t->top, t->bot, t->etext-t->text);
199 twhilite(t, ep->sel0, ep->sel1, 1);
201 Point pl_getsizeedit(Panel *p, Point children){
203 return pl_boxsize(((Edit *)p->data)->minsize, p->state);
205 void pl_childspaceedit(Panel *g, Point *ul, Point *size){
208 void pl_freeedit(Panel *p){
211 if(ep->t!=nil) twfree(ep->t);
214 void plinitedit(Panel *v, int flags, Point minsize, Rune *text, int ntext, void (*hit)(Panel *)){
222 v->getsize=pl_getsizeedit;
223 v->childspace=pl_childspaceedit;
225 v->snarf=pl_snarfedit;
226 v->paste=pl_pasteedit;
232 if(ep->t!=0) twfree(ep->t);
236 v->scroll=pl_scrolledit;
238 v->scr.size=Pt(ntext,0);
240 Panel *pledit(Panel *parent, int flags, Point minsize, Rune *text, int ntext, void (*hit)(Panel *)){
242 v=pl_newpanel(parent, sizeof(Edit));
243 ((Edit *)v->data)->t=0;
244 plinitedit(v, flags, minsize, text, ntext, hit);
247 void plescroll(Panel *p, int top){
248 twscroll(((Edit *)p->data)->t, top);
250 void plegetsel(Panel *p, int *sel0, int *sel1){
256 int plelen(Panel *p){
258 t=((Edit *)p->data)->t;
260 return t->etext-t->text;
262 Rune *pleget(Panel *p){
263 return ((Edit *)p->data)->t->text;
265 void plesel(Panel *p, int sel0, int sel1){
269 twhilite(ep->t, ep->sel0, ep->sel1, 0);
272 twhilite(ep->t, ep->sel0, ep->sel1, 1);
274 void plepaste(Panel *p, Rune *text, int ntext){
278 twhilite(ep->t, ep->sel0, ep->sel1, 0);
279 twreplace(ep->t, ep->sel0, ep->sel1, text, ntext);
280 ep->sel1=ep->sel0+ntext;
281 twhilite(ep->t, ep->sel0, ep->sel1, 1);
282 p->scr.size.y=ep->t->etext-ep->t->text;
283 p->scr.pos.y=ep->t->top;
285 void plemove(Panel *p, Point d){
288 if(ep->t && !eqpt(d, Pt(0,0))) twmove(ep->t, d);