#include <u.h>#include <libc.h>#include <draw.h>#include <event.h>#include <panel.h>#include "pldefs.h"#include <keyboard.h> typedef struct Entry Entry;struct Entry{ char *entry; char *entp; char *eent; void (*hit)(Panel *, char *); Point minsize;};#define SLACK 7 /* enough for one extra rune and ◀ and a nul */char *pl_snarfentry(Panel *p){ Entry *ep; int n; if(p->flags&USERFL) /* no snarfing from password entry */ return nil; ep=p->data; n=utfnlen(ep->entry, ep->entp-ep->entry); if(n<1) return nil; return smprint("%.*s", n, ep->entry);}void pl_pasteentry(Panel *p, char *s){ Entry *ep; char *e; int n, m; ep=p->data; n=ep->entp-ep->entry; m=strlen(s); e=pl_erealloc(ep->entry,n+m+SLACK); ep->entry=e; e+=n; strncpy(e, s, m); e+=m; *e='\0'; ep->entp=ep->eent=e; pldraw(p, p->b);}void pl_drawentry(Panel *p){ Rectangle r; Entry *ep; char *s; ep=p->data; r=pl_box(p->b, p->r, p->state); s=ep->entry; if(p->flags & USERFL){ char *p; s=strdup(s); for(p=s; *p; p++) *p='*'; } if(stringwidth(font, s)<=r.max.x-r.min.x) pl_drawicon(p->b, r, PLACEW, 0, s); else pl_drawicon(p->b, r, PLACEE, 0, s); if(s != ep->entry) free(s);}int pl_hitentry(Panel *p, Mouse *m){ if((m->buttons&7)==1){ plgrabkb(p); p->state=DOWN; pldraw(p, p->b); while(m->buttons&1){ int old; old=m->buttons; if(display->bufp > display->buf) flushimage(display, 1); *m=emouse(); if((old&7)==1){ if((m->buttons&7)==3){ Entry *ep; plsnarf(p); /* cut */ ep=p->data; ep->entp=ep->entry; *ep->entp='\0'; pldraw(p, p->b); } if((m->buttons&7)==5) plpaste(p); } } p->state=UP; pldraw(p, p->b); } return 0;}void pl_typeentry(Panel *p, Rune c){ int n; Entry *ep; ep=p->data; switch(c){ case '\n': case '\r': *ep->entp='\0'; if(ep->hit) ep->hit(p, ep->entry); return; case Kesc: plsnarf(p); /* no break */ case Kdel: /* clear */ case Knack: /* ^U: erase line */ ep->entp=ep->entry; *ep->entp='\0'; break; case Kbs: /* ^H: erase character */ while(ep->entp!=ep->entry && !pl_rune1st(ep->entp[-1])) *--ep->entp='\0'; if(ep->entp!=ep->entry) *--ep->entp='\0'; break; case Ketb: /* ^W: erase word */ while(ep->entp!=ep->entry && !pl_idchar(ep->entp[-1])) --ep->entp; while(ep->entp!=ep->entry && pl_idchar(ep->entp[-1])) --ep->entp; *ep->entp='\0'; break; default: if(c < 0x20 || (c & 0xFF00) == KF || (c & 0xFF00) == Spec) break; ep->entp+=runetochar(ep->entp, &c); if(ep->entp>ep->eent){ n=ep->entp-ep->entry; ep->entry=pl_erealloc(ep->entry, n+100+SLACK); ep->entp=ep->entry+n; ep->eent=ep->entp+100; } *ep->entp='\0'; break; } pldraw(p, p->b);}Point pl_getsizeentry(Panel *p, Point children){ USED(children); return pl_boxsize(((Entry *)p->data)->minsize, p->state);}void pl_childspaceentry(Panel *p, Point *ul, Point *size){ USED(p, ul, size);}void pl_freeentry(Panel *p){ Entry *ep; ep = p->data; free(ep->entry); ep->entry = ep->eent = ep->entp = 0;}void plinitentry(Panel *v, int flags, int wid, char *str, void (*hit)(Panel *, char *)){ int elen; Entry *ep; ep=v->data; v->flags=flags|LEAF; v->state=UP; v->draw=pl_drawentry; v->hit=pl_hitentry; v->type=pl_typeentry; v->getsize=pl_getsizeentry; v->childspace=pl_childspaceentry; ep->minsize=Pt(wid, font->height); v->free=pl_freeentry; v->snarf=pl_snarfentry; v->paste=pl_pasteentry; elen=100; if(str) elen+=strlen(str); ep->entry=pl_erealloc(ep->entry, elen+SLACK); ep->eent=ep->entry+elen; strecpy(ep->entry, ep->eent, str ? str : ""); ep->entp=ep->entry+strlen(ep->entry); ep->hit=hit; v->kind="entry";}Panel *plentry(Panel *parent, int flags, int wid, char *str, void (*hit)(Panel *, char *)){ Panel *v; v=pl_newpanel(parent, sizeof(Entry)); plinitentry(v, flags, wid, str, hit); return v;}char *plentryval(Panel *p){ Entry *ep; ep=p->data; *ep->entp='\0'; return ep->entry;}
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
#include <panel.h>
#include "pldefs.h"
#include <keyboard.h>
typedef struct Entry Entry;
struct Entry{
char *entry;
char *entp;
char *eent;
void (*hit)(Panel *, char *);
Point minsize;
};
#define SLACK 7 /* enough for one extra rune and ◀ and a nul */
char *pl_snarfentry(Panel *p){
Entry *ep;
int n;
if(p->flags&USERFL) /* no snarfing from password entry */
return nil;
ep=p->data;
n=utfnlen(ep->entry, ep->entp-ep->entry);
if(n<1) return nil;
return smprint("%.*s", n, ep->entry);
}
void pl_pasteentry(Panel *p, char *s){
Entry *ep;
char *e;
int n, m;
ep=p->data;
n=ep->entp-ep->entry;
m=strlen(s);
e=pl_erealloc(ep->entry,n+m+SLACK);
ep->entry=e;
e+=n;
strncpy(e, s, m);
e+=m;
*e='\0';
ep->entp=ep->eent=e;
pldraw(p, p->b);
}
void pl_drawentry(Panel *p){
Rectangle r;
Entry *ep;
char *s;
ep=p->data;
r=pl_box(p->b, p->r, p->state);
s=ep->entry;
if(p->flags & USERFL){
char *p;
s=strdup(s);
for(p=s; *p; p++)
*p='*';
}
if(stringwidth(font, s)<=r.max.x-r.min.x)
pl_drawicon(p->b, r, PLACEW, 0, s);
else
pl_drawicon(p->b, r, PLACEE, 0, s);
if(s != ep->entry)
free(s);
}
int pl_hitentry(Panel *p, Mouse *m){
if((m->buttons&7)==1){
plgrabkb(p);
p->state=DOWN;
pldraw(p, p->b);
while(m->buttons&1){
int old;
old=m->buttons;
if(display->bufp > display->buf)
flushimage(display, 1);
*m=emouse();
if((old&7)==1){
if((m->buttons&7)==3){
Entry *ep;
plsnarf(p);
/* cut */
ep=p->data;
ep->entp=ep->entry;
*ep->entp='\0';
pldraw(p, p->b);
}
if((m->buttons&7)==5)
plpaste(p);
}
}
p->state=UP;
pldraw(p, p->b);
}
return 0;
}
void pl_typeentry(Panel *p, Rune c){
int n;
Entry *ep;
ep=p->data;
switch(c){
case '\n':
case '\r':
*ep->entp='\0';
if(ep->hit) ep->hit(p, ep->entry);
return;
case Kesc:
plsnarf(p);
/* no break */
case Kdel: /* clear */
case Knack: /* ^U: erase line */
ep->entp=ep->entry;
*ep->entp='\0';
break;
case Kbs: /* ^H: erase character */
while(ep->entp!=ep->entry && !pl_rune1st(ep->entp[-1])) *--ep->entp='\0';
if(ep->entp!=ep->entry) *--ep->entp='\0';
break;
case Ketb: /* ^W: erase word */
while(ep->entp!=ep->entry && !pl_idchar(ep->entp[-1]))
--ep->entp;
while(ep->entp!=ep->entry && pl_idchar(ep->entp[-1]))
--ep->entp;
*ep->entp='\0';
break;
default:
if(c < 0x20 || (c & 0xFF00) == KF || (c & 0xFF00) == Spec)
break;
ep->entp+=runetochar(ep->entp, &c);
if(ep->entp>ep->eent){
n=ep->entp-ep->entry;
ep->entry=pl_erealloc(ep->entry, n+100+SLACK);
ep->entp=ep->entry+n;
ep->eent=ep->entp+100;
}
*ep->entp='\0';
break;
}
pldraw(p, p->b);
}
Point pl_getsizeentry(Panel *p, Point children){
USED(children);
return pl_boxsize(((Entry *)p->data)->minsize, p->state);
}
void pl_childspaceentry(Panel *p, Point *ul, Point *size){
USED(p, ul, size);
}
void pl_freeentry(Panel *p){
Entry *ep;
ep = p->data;
free(ep->entry);
ep->entry = ep->eent = ep->entp = 0;
}
void plinitentry(Panel *v, int flags, int wid, char *str, void (*hit)(Panel *, char *)){
int elen;
Entry *ep;
ep=v->data;
v->flags=flags|LEAF;
v->state=UP;
v->draw=pl_drawentry;
v->hit=pl_hitentry;
v->type=pl_typeentry;
v->getsize=pl_getsizeentry;
v->childspace=pl_childspaceentry;
ep->minsize=Pt(wid, font->height);
v->free=pl_freeentry;
v->snarf=pl_snarfentry;
v->paste=pl_pasteentry;
elen=100;
if(str) elen+=strlen(str);
ep->entry=pl_erealloc(ep->entry, elen+SLACK);
ep->eent=ep->entry+elen;
strecpy(ep->entry, ep->eent, str ? str : "");
ep->entp=ep->entry+strlen(ep->entry);
ep->hit=hit;
v->kind="entry";
}
Panel *plentry(Panel *parent, int flags, int wid, char *str, void (*hit)(Panel *, char *)){
Panel *v;
v=pl_newpanel(parent, sizeof(Entry));
plinitentry(v, flags, wid, str, hit);
return v;
}
char *plentryval(Panel *p){
Entry *ep;
ep=p->data;
*ep->entp='\0';
return ep->entry;
}