mothra: cut/snarf in entry and edit panels
This commit is contained in:
parent
4da9e8aa4f
commit
d8b1af77d0
8 changed files with 117 additions and 70 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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){
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue