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_resetinput(Panel *, 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 *nullgen(Panel *, int);
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;
break;
case TEXTWIN:
menu=plgroup(0,0);
f->p=plframe(0,0);
pllabel(f->p, PACKN|FILLX, f->name);
scrl=plscrollbar(f->p, PACKW|FILLY);
pop=plpopup(f->p, PACKN|FILLX, 0, menu, 0);
f->textwin=pledit(pop, EXPAND, Pt(f->cols*chrwidth, f->rows*font->height),
0, 0, h_edit);
f->textwin=pledit(f->p, EXPAND, Pt(f->cols*chrwidth, f->rows*font->height),
0, 0, 0);
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);
break;
case INDEX:
@ -457,34 +445,6 @@ void h_resetinput(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 len;
len=0;

View file

@ -24,9 +24,9 @@
typedef struct Edit Edit;
struct Edit{
Point minsize;
void (*hit)(Panel *);
int sel0, sel1;
Textwin *t;
void (*hit)(Panel *);
Rune *text;
int ntext;
};
@ -48,6 +48,39 @@ void pl_drawedit(Panel *p){
if(sb && sb->setscrollbar)
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:
* If ep->sel0==ep->sel1 on entry and the
@ -73,7 +106,13 @@ int pl_hitedit(Panel *p, Mouse *m){
twselect(ep->t, m);
ep->sel0=ep->t->sel0;
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;
}
@ -124,6 +163,9 @@ void pl_typeedit(Panel *p, Rune c){
t->b=p->b;
twhilite(t, ep->sel0, ep->sel1, 0);
switch(c){
case Kesc:
pl_snarfedit(p, 1);
break;
case Kbs: /* ^H: erase character */
if(ep->sel0!=0) --ep->sel0;
twreplace(t, ep->sel0, ep->sel1, 0, 0);

View file

@ -15,6 +15,35 @@ struct Entry{
Point minsize;
};
#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){
Rectangle r;
Entry *ep;
@ -37,17 +66,25 @@ void pl_drawentry(Panel *p){
free(s);
}
int pl_hitentry(Panel *p, Mouse *m){
int oldstate;
oldstate=p->state;
if(m->buttons&OUT)
p->state=UP;
else if(m->buttons&7)
if((m->buttons&OUT)==0 && (m->buttons&7)){
plgrabkb(p);
p->state=DOWN;
else{ /* mouse inside, but no buttons down */
if(p->state==DOWN) plgrabkb(p);
p->state=UP;
pldraw(p, p->b);
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;
pldraw(p, p->b);
}
if(p->state!=oldstate) pldraw(p, p->b);
return 0;
}
void pl_typeentry(Panel *p, Rune c){
@ -60,6 +97,9 @@ void pl_typeentry(Panel *p, Rune c){
*ep->entp='\0';
if(ep->hit) ep->hit(p, ep->entry);
return;
case Kesc:
pl_snarfentry(p, 1);
return;
case Knack: /* ^U: erase line */
ep->entp=ep->entry;
*ep->entp='\0';
@ -76,7 +116,7 @@ void pl_typeentry(Panel *p, Rune c){
*ep->entp='\0';
break;
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;
ep->entp+=runetochar(ep->entp, &c);
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 MAXY 0x2000 /* make y size as big as biggest sibling's */
#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

View file

@ -21,6 +21,7 @@ int pl_hitpopup(Panel *g, Mouse *m){
Panel *p;
Point d;
Popup *pp;
pp=g->data;
if(g->state==UP){
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);
flushimage(display, 1);
freeimage(pp->save);
pp->save=0;
}
pl_invis(p, 1);
}

View file

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

View file

@ -26,6 +26,9 @@
#include <event.h>
#include <panel.h>
#include "pldefs.h"
#define SLACK 100
/*
* 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){
int nloc;
if(l>t->eloc-t->loc){
nloc=l+100;
if(l>=t->eloc-t->loc){
nloc=l+SLACK;
t->loc=realloc(t->loc, nloc*sizeof(Point));
if(t->loc==0){
fprint(2, "No mem in tw_storeloc\n");
@ -226,7 +229,7 @@ void twselect(Textwin *t, Mouse *m){
twhilite(t, sel0, sel1, 1);
for(;;){
*m=emouse();
if(m->buttons==0) break;
if((m->buttons&7)!=1) break;
newsel=twpt2rune(t, m->xy);
newp=tw_rune2pt(t, newsel);
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;
Rune *ntext;
olen=t->etext-t->text;
nlen=olen+r0-r1+nins;
nlen=olen+nins-(r1-r0);
tlen=t->eslack-t->text;
if(nlen>tlen){
tlen=nlen+100;
ntext=malloc(tlen*sizeof(Rune));
memmove(ntext, t->text, r0*sizeof(Rune));
memmove(ntext+r0+nins, t->text+r1, (olen-r1)*sizeof(Rune));
tlen=nlen+SLACK;
if((ntext=realloc(t->text, tlen*sizeof(Rune)))==0)
return;
t->text=ntext;
t->eslack=ntext+tlen;
}
else if(olen!=nlen)
if(olen!=nlen)
memmove(t->text+r0+nins, t->text+r1, (olen-r1)*sizeof(Rune));
if(nins!=0) /* ins can be 0 if nins==0 */
memmove(t->text+r0, ins, nins*sizeof(Rune));
@ -444,20 +446,20 @@ Textwin *twnew(Image *b, Font *f, Rune *text, int ntext){
Textwin *t;
t=malloc(sizeof(Textwin));
if(t==0) return 0;
t->text=malloc((ntext+100)*sizeof(Rune));
t->text=malloc((ntext+SLACK)*sizeof(Rune));
if(t->text==0){
free(t);
return 0;
}
t->loc=malloc(100*sizeof(Point));
t->loc=malloc(SLACK*sizeof(Point));
if(t->loc==0){
free(t->text);
free(t);
return 0;
}
t->eloc=t->loc+100;
t->eloc=t->loc+SLACK;
t->etext=t->text+ntext;
t->eslack=t->etext+100;
t->eslack=t->etext+SLACK;
if(ntext) memmove(t->text, text, ntext*sizeof(Rune));
t->top=0;
t->bot=0;

View file

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