henesyinit from p9fce6d0435 years agoHistory
127 lines · 2.9 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <libg.h>#include <panel.h>#include "pldefs.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 */void pl_drawentry(Panel *p){	Rectangle r;	Entry *ep;	ep=p->data;	r=pl_box(p->b, p->r, p->state);	if(strwidth(font, ep->entry)<=r.max.x-r.min.x)		pl_drawicon(p->b, r, PLACEW, 0, ep->entry);	else		pl_drawicon(p->b, r, PLACEE, 0, ep->entry);}int pl_hitentry(Panel *p, Mouse *m){	int oldstate;	oldstate=p->state;	if(m->buttons&OUT)		p->state=UP;	else if(m->buttons&7)		p->state=DOWN;	else{	/* mouse inside, but no buttons down */		if(p->state==DOWN) plgrabkb(p);		p->state=UP;	}	if(p->state!=oldstate) 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 025:	/* ctrl-u */		ep->entp=ep->entry;		*ep->entp='\0';		break;	case '\b':		while(ep->entp!=ep->entry && !pl_rune1st(ep->entp[-1])) *--ep->entp='\0';		if(ep->entp!=ep->entry) *--ep->entp='\0';		break;	case 027:	/* ctrl-w */		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:		ep->entp+=runetochar(ep->entp, &c);		if(ep->entp>ep->eent){			n=ep->entp-ep->entry;			ep->entry=realloc(ep->entry, n+100+SLACK);			if(ep->entry==0){				fprint(2, "can't realloc in pl_typeentry\n");				exits("no mem");			}			ep->entp=ep->entry+n;			ep->eent=ep->entp+100;		}		break;	}	strcpy(ep->entp, "◀");	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){	free(((Entry *)p->data)->entry);}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;	elen=100;	if(str) elen+=strlen(str);	ep->entry=pl_emalloc(elen+SLACK);	ep->eent=ep->entry+elen;	if(str)		strcpy(ep->entry, str);	else ep->entry[0]='\0';	ep->entp=ep->entry+strlen(ep->entry);	strcat(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;}