mothra: cut/snarf in entry and edit panels

This commit is contained in:
cinap_lenrek 2011-11-08 06:16:08 +01:00
parent 4da9e8aa4f
commit d8b1af77d0
8 changed files with 117 additions and 70 deletions

View file

@ -64,10 +64,6 @@ void h_submittype(Panel *, char *);
void h_submitindex(Panel *, char *); void h_submitindex(Panel *, char *);
void h_resetinput(Panel *, int); void h_resetinput(Panel *, int);
void h_select(Panel *, int, int); void h_select(Panel *, int, int);
void h_cut(Panel *, int);
void h_paste(Panel *, int);
void h_snarf(Panel *, int);
void h_edit(Panel *);
char *selgen(Panel *, int); char *selgen(Panel *, int);
char *nullgen(Panel *, int); char *nullgen(Panel *, int);
Field *newfield(Form *form){ Field *newfield(Form *form){
@ -377,20 +373,12 @@ void mkfieldpanel(Rtext *t){
f->p->fixedsize.x=f->pulldown->r.max.x-f->pulldown->r.min.x; f->p->fixedsize.x=f->pulldown->r.max.x-f->pulldown->r.min.x;
break; break;
case TEXTWIN: case TEXTWIN:
menu=plgroup(0,0);
f->p=plframe(0,0); f->p=plframe(0,0);
pllabel(f->p, PACKN|FILLX, f->name); pllabel(f->p, PACKN|FILLX, f->name);
scrl=plscrollbar(f->p, PACKW|FILLY); scrl=plscrollbar(f->p, PACKW|FILLY);
pop=plpopup(f->p, PACKN|FILLX, 0, menu, 0); f->textwin=pledit(f->p, EXPAND, Pt(f->cols*chrwidth, f->rows*font->height),
f->textwin=pledit(pop, EXPAND, Pt(f->cols*chrwidth, f->rows*font->height), 0, 0, 0);
0, 0, h_edit);
f->textwin->userp=f; f->textwin->userp=f;
button=plbutton(menu, PACKN|FILLX, "cut", h_cut);
button->userp=f->textwin;
button=plbutton(menu, PACKN|FILLX, "paste", h_paste);
button->userp=f->textwin;
button=plbutton(menu, PACKN|FILLX, "snarf", h_snarf);
button->userp=f->textwin;
plscroll(f->textwin, 0, scrl); plscroll(f->textwin, 0, scrl);
break; break;
case INDEX: case INDEX:
@ -457,34 +445,6 @@ void h_resetinput(Panel *p, int){
} }
void h_buttoninput(Panel *p, int){ void h_buttoninput(Panel *p, int){
} }
void h_edit(Panel *p){
plgrabkb(p);
}
Rune *snarfbuf=0;
int nsnarfbuf=0;
void h_snarf(Panel *p, int){
int s0, s1;
Rune *text;
p=p->userp;
plegetsel(p, &s0, &s1);
if(s0==s1) return;
text=pleget(p);
if(snarfbuf) free(snarfbuf);
nsnarfbuf=s1-s0;
snarfbuf=malloc(nsnarfbuf*sizeof(Rune));
if(snarfbuf==0){
fprint(2, "No mem\n");
exits("no mem");
}
memmove(snarfbuf, text+s0, nsnarfbuf*sizeof(Rune));
}
void h_cut(Panel *p, int b){
h_snarf(p, b);
plepaste(p->userp, 0, 0);
}
void h_paste(Panel *p, int){
plepaste(p->userp, snarfbuf, nsnarfbuf);
}
int ulen(char *s){ int ulen(char *s){
int len; int len;
len=0; len=0;

View file

@ -24,9 +24,9 @@
typedef struct Edit Edit; typedef struct Edit Edit;
struct Edit{ struct Edit{
Point minsize; Point minsize;
void (*hit)(Panel *);
int sel0, sel1; int sel0, sel1;
Textwin *t; Textwin *t;
void (*hit)(Panel *);
Rune *text; Rune *text;
int ntext; int ntext;
}; };
@ -48,6 +48,39 @@ void pl_drawedit(Panel *p){
if(sb && sb->setscrollbar) if(sb && sb->setscrollbar)
sb->setscrollbar(sb, ep->t->top, ep->t->bot, ep->t->etext-ep->t->text); sb->setscrollbar(sb, ep->t->top, ep->t->bot, ep->t->etext-ep->t->text);
} }
void pl_snarfedit(Panel *p, int cut){
int fd, n, s0, s1;
char *s;
Rune *t;
if((fd=open("/dev/snarf", cut ? OWRITE|OTRUNC : OREAD))<0)
return;
if(cut){
t=pleget(p);
plegetsel(p, &s0, &s1);
if(t==0 || s0>=s1){
close(fd);
return;
}
s = smprint("%.*S", s1-s0, t+s0);
if((n = strlen(s))>0)
write(fd, s, n);
free(s);
plepaste(p, 0, 0);
}else{
if((s=malloc(4096))==0){
close(fd);
return;
}
if((n=readn(fd, s, 4096))<0)
n=0;
t=runesmprint("%.*s", n, s);
plepaste(p, t, runestrlen(t));
free(s);
free(t);
}
close(fd);
}
/* /*
* Should do double-clicks: * Should do double-clicks:
* If ep->sel0==ep->sel1 on entry and the * If ep->sel0==ep->sel1 on entry and the
@ -73,7 +106,13 @@ int pl_hitedit(Panel *p, Mouse *m){
twselect(ep->t, m); twselect(ep->t, m);
ep->sel0=ep->t->sel0; ep->sel0=ep->t->sel0;
ep->sel1=ep->t->sel1; ep->sel1=ep->t->sel1;
if(ep->hit) ep->hit(p); plgrabkb(p);
if((m->buttons&7)==3)
pl_snarfedit(p, 1);
else if((m->buttons&7)==5)
pl_snarfedit(p, 0);
else if(ep->hit)
(*ep->hit)(p);
} }
return 0; return 0;
} }
@ -124,6 +163,9 @@ void pl_typeedit(Panel *p, Rune c){
t->b=p->b; t->b=p->b;
twhilite(t, ep->sel0, ep->sel1, 0); twhilite(t, ep->sel0, ep->sel1, 0);
switch(c){ switch(c){
case Kesc:
pl_snarfedit(p, 1);
break;
case Kbs: /* ^H: erase character */ case Kbs: /* ^H: erase character */
if(ep->sel0!=0) --ep->sel0; if(ep->sel0!=0) --ep->sel0;
twreplace(t, ep->sel0, ep->sel1, 0, 0); twreplace(t, ep->sel0, ep->sel1, 0, 0);

View file

@ -15,6 +15,35 @@ struct Entry{
Point minsize; Point minsize;
}; };
#define SLACK 7 /* enough for one extra rune and ◀ and a nul */ #define SLACK 7 /* enough for one extra rune and ◀ and a nul */
void pl_snarfentry(Panel *p, int cut){
Entry *ep;
int fd, n;
char *s;
ep=p->data;
if((fd=open("/dev/snarf", cut ? OWRITE|OTRUNC : OREAD))<0)
return;
if(cut){
if((n=ep->entp-ep->entry)>0)
write(fd, ep->entry, n);
ep->entp=ep->entry;
}else{
if((s=malloc(1024+SLACK))==0){
close(fd);
return;
}
if((n=readn(fd, s, 1024))<0)
n=0;
free(ep->entry);
s=realloc(s, n+SLACK);
ep->entry=s;
ep->eent=s+n+SLACK;
ep->entp=s+n;
}
close(fd);
*ep->entp='\0';
pldraw(p, p->b);
}
void pl_drawentry(Panel *p){ void pl_drawentry(Panel *p){
Rectangle r; Rectangle r;
Entry *ep; Entry *ep;
@ -37,17 +66,25 @@ void pl_drawentry(Panel *p){
free(s); free(s);
} }
int pl_hitentry(Panel *p, Mouse *m){ int pl_hitentry(Panel *p, Mouse *m){
int oldstate; if((m->buttons&OUT)==0 && (m->buttons&7)){
oldstate=p->state; plgrabkb(p);
if(m->buttons&OUT)
p->state=UP;
else if(m->buttons&7)
p->state=DOWN; p->state=DOWN;
else{ /* mouse inside, but no buttons down */ pldraw(p, p->b);
if(p->state==DOWN) plgrabkb(p); while(m->buttons&7){
int old;
old=m->buttons;
*m=emouse();
if((old&7)==1){
if((m->buttons&7)==3)
pl_snarfentry(p, 1);
if((m->buttons&7)==5)
pl_snarfentry(p, 0);
}
}
p->state=UP; p->state=UP;
pldraw(p, p->b);
} }
if(p->state!=oldstate) pldraw(p, p->b);
return 0; return 0;
} }
void pl_typeentry(Panel *p, Rune c){ void pl_typeentry(Panel *p, Rune c){
@ -60,6 +97,9 @@ void pl_typeentry(Panel *p, Rune c){
*ep->entp='\0'; *ep->entp='\0';
if(ep->hit) ep->hit(p, ep->entry); if(ep->hit) ep->hit(p, ep->entry);
return; return;
case Kesc:
pl_snarfentry(p, 1);
return;
case Knack: /* ^U: erase line */ case Knack: /* ^U: erase line */
ep->entp=ep->entry; ep->entp=ep->entry;
*ep->entp='\0'; *ep->entp='\0';
@ -76,7 +116,7 @@ void pl_typeentry(Panel *p, Rune c){
*ep->entp='\0'; *ep->entp='\0';
break; break;
default: default:
if(c < 0x20 || c == Kesc || c == Kdel || (c & 0xFF00) == KF || (c & 0xFF00) == Spec) if(c < 0x20 || c == Kdel || (c & 0xFF00) == KF || (c & 0xFF00) == Spec)
break; break;
ep->entp+=runetochar(ep->entp, &c); ep->entp+=runetochar(ep->entp, &c);
if(ep->entp>ep->eent){ if(ep->entp>ep->eent){

View file

@ -85,7 +85,7 @@ struct Panel{
#define MAXX 0x1000 /* make x size as big as biggest sibling's */ #define MAXX 0x1000 /* make x size as big as biggest sibling's */
#define MAXY 0x2000 /* make y size as big as biggest sibling's */ #define MAXY 0x2000 /* make y size as big as biggest sibling's */
#define BITMAP 0x4000 /* text argument is a bitmap, not a string */ #define BITMAP 0x4000 /* text argument is a bitmap, not a string */
#define USERFL 0x100000 /* user flag */ #define USERFL 0x100000 /* start of user flag */
/* /*
* An extra bit in Mouse.buttons * An extra bit in Mouse.buttons

View file

@ -21,6 +21,7 @@ int pl_hitpopup(Panel *g, Mouse *m){
Panel *p; Panel *p;
Point d; Point d;
Popup *pp; Popup *pp;
pp=g->data; pp=g->data;
if(g->state==UP){ if(g->state==UP){
switch(m->buttons&7){ switch(m->buttons&7){
@ -66,6 +67,7 @@ int pl_hitpopup(Panel *g, Mouse *m){
draw(g->b, p->r, pp->save, 0, p->r.min); draw(g->b, p->r, pp->save, 0, p->r.min);
flushimage(display, 1); flushimage(display, 1);
freeimage(pp->save); freeimage(pp->save);
pp->save=0;
} }
pl_invis(p, 1); pl_invis(p, 1);
} }

View file

@ -113,6 +113,7 @@ int pl_hittextview(Panel *p, Mouse *m){
tp=p->data; tp=p->data;
oldhitword=tp->hitword; oldhitword=tp->hitword;
hitme=0; hitme=0;
pl_passon(oldhitword, m); pl_passon(oldhitword, m);
if(m->buttons&OUT) if(m->buttons&OUT)
p->state=UP; p->state=UP;

View file

@ -26,6 +26,9 @@
#include <event.h> #include <event.h>
#include <panel.h> #include <panel.h>
#include "pldefs.h" #include "pldefs.h"
#define SLACK 100
/* /*
* Is text at point a before or after that at point b? * Is text at point a before or after that at point b?
*/ */
@ -61,8 +64,8 @@ Point tw_rune2pt(Textwin *t, int i){
*/ */
void tw_storeloc(Textwin *t, int l, Point p){ void tw_storeloc(Textwin *t, int l, Point p){
int nloc; int nloc;
if(l>t->eloc-t->loc){ if(l>=t->eloc-t->loc){
nloc=l+100; nloc=l+SLACK;
t->loc=realloc(t->loc, nloc*sizeof(Point)); t->loc=realloc(t->loc, nloc*sizeof(Point));
if(t->loc==0){ if(t->loc==0){
fprint(2, "No mem in tw_storeloc\n"); fprint(2, "No mem in tw_storeloc\n");
@ -226,7 +229,7 @@ void twselect(Textwin *t, Mouse *m){
twhilite(t, sel0, sel1, 1); twhilite(t, sel0, sel1, 1);
for(;;){ for(;;){
*m=emouse(); *m=emouse();
if(m->buttons==0) break; if((m->buttons&7)!=1) break;
newsel=twpt2rune(t, m->xy); newsel=twpt2rune(t, m->xy);
newp=tw_rune2pt(t, newsel); newp=tw_rune2pt(t, newsel);
if(eqpt(newp, p0)) newp=addpt(newp, Pt(1, 0)); if(eqpt(newp, p0)) newp=addpt(newp, Pt(1, 0));
@ -389,17 +392,16 @@ void twreplace(Textwin *t, int r0, int r1, Rune *ins, int nins){
int olen, nlen, tlen, dtop; int olen, nlen, tlen, dtop;
Rune *ntext; Rune *ntext;
olen=t->etext-t->text; olen=t->etext-t->text;
nlen=olen+r0-r1+nins; nlen=olen+nins-(r1-r0);
tlen=t->eslack-t->text; tlen=t->eslack-t->text;
if(nlen>tlen){ if(nlen>tlen){
tlen=nlen+100; tlen=nlen+SLACK;
ntext=malloc(tlen*sizeof(Rune)); if((ntext=realloc(t->text, tlen*sizeof(Rune)))==0)
memmove(ntext, t->text, r0*sizeof(Rune)); return;
memmove(ntext+r0+nins, t->text+r1, (olen-r1)*sizeof(Rune));
t->text=ntext; t->text=ntext;
t->eslack=ntext+tlen; t->eslack=ntext+tlen;
} }
else if(olen!=nlen) if(olen!=nlen)
memmove(t->text+r0+nins, t->text+r1, (olen-r1)*sizeof(Rune)); memmove(t->text+r0+nins, t->text+r1, (olen-r1)*sizeof(Rune));
if(nins!=0) /* ins can be 0 if nins==0 */ if(nins!=0) /* ins can be 0 if nins==0 */
memmove(t->text+r0, ins, nins*sizeof(Rune)); memmove(t->text+r0, ins, nins*sizeof(Rune));
@ -444,20 +446,20 @@ Textwin *twnew(Image *b, Font *f, Rune *text, int ntext){
Textwin *t; Textwin *t;
t=malloc(sizeof(Textwin)); t=malloc(sizeof(Textwin));
if(t==0) return 0; if(t==0) return 0;
t->text=malloc((ntext+100)*sizeof(Rune)); t->text=malloc((ntext+SLACK)*sizeof(Rune));
if(t->text==0){ if(t->text==0){
free(t); free(t);
return 0; return 0;
} }
t->loc=malloc(100*sizeof(Point)); t->loc=malloc(SLACK*sizeof(Point));
if(t->loc==0){ if(t->loc==0){
free(t->text); free(t->text);
free(t); free(t);
return 0; return 0;
} }
t->eloc=t->loc+100; t->eloc=t->loc+SLACK;
t->etext=t->text+ntext; t->etext=t->text+ntext;
t->eslack=t->etext+100; t->eslack=t->etext+SLACK;
if(ntext) memmove(t->text, text, ntext*sizeof(Rune)); if(ntext) memmove(t->text, text, ntext*sizeof(Rune));
t->top=0; t->top=0;
t->bot=0; t->bot=0;

View file

@ -1121,8 +1121,7 @@ mothon(Www *w, int on)
void snarf(Panel *p){ void snarf(Panel *p){
int fd; int fd;
fd=create("/dev/snarf", OWRITE, 0666); if((fd=open("/dev/snarf", OWRITE|OTRUNC))>=0){
if(fd>=0){
fprint(fd, "%s", urlstr(selection)); fprint(fd, "%s", urlstr(selection));
close(fd); close(fd);
} }
@ -1130,7 +1129,8 @@ void snarf(Panel *p){
void paste(Panel *p){ void paste(Panel *p){
char buf[1024]; char buf[1024];
int n, len, fd; int n, len, fd;
fd=open("/dev/snarf", OREAD); if((fd=open("/dev/snarf", OREAD))<0)
return;
strncpy(buf, plentryval(p), sizeof(buf)); strncpy(buf, plentryval(p), sizeof(buf));
len=strlen(buf); len=strlen(buf);
n=read(fd, buf+len, sizeof(buf)-len-1); n=read(fd, buf+len, sizeof(buf)-len-1);