telephil9initial importc9c50ad6 years agoHistory
192 lines · 3.9 KB · C
RawDownload
#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;}