shithub: gopher

ref: b4e186a54a0c902854f7d709d1edb31946216065
dir: gopher/libpanel/message.c

View raw version
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
#include <panel.h>
#include "pldefs.h"
typedef struct Message Message;
struct Message{
	char *text;
	Point minsize;
};
void pl_textmsg(Image *b, Rectangle r, Font *f, char *s){
	char *start, *end;	/* of line */
	Point where;
	int lwid, c, wid;
	where=r.min;
	wid=r.max.x-r.min.x;
	do{
		start=s;
		lwid=0;
		end=s;
		do{
			for(;*s!=' ' && *s!='\0';s=pl_nextrune(s)) lwid+=pl_runewidth(f, s);
			if(lwid>wid) break;
			end=s;
			for(;*s==' ';s=pl_nextrune(s)) lwid+=pl_runewidth(f, s);
		}while(*s!='\0');
		if(end==start)	/* can't even fit one word on line! */
			end=s;
		c=*end;
		*end='\0';
		string(b, where, display->black, ZP, f, start);
		*end=c;
		where.y+=font->height;
		s=end;
		while(*s==' ') s=pl_nextrune(s);
	}while(*s!='\0');
}
Point pl_foldsize(Font *f, char *s, int wid){
	char *start, *end;	/* of line */
	Point size;
	int lwid, ewid;
	size=Pt(0,0);
	do{
		start=s;
		lwid=0;
		end=s;
		ewid=lwid;
		do{
			for(;*s!=' ' && *s!='\0';s=pl_nextrune(s)) lwid+=pl_runewidth(f, s);
			if(lwid>wid) break;
			end=s;
			ewid=lwid;
			for(;*s==' ';s=pl_nextrune(s)) lwid+=pl_runewidth(f, s);
		}while(*s!='\0');
		if(end==start){	/* can't even fit one word on line! */
			ewid=lwid;
			end=s;
		}
		if(ewid>size.x) size.x=ewid;
		size.y+=font->height;
		s=end;
		while(*s==' ') s=pl_nextrune(s);
	}while(*s!='\0');
	return size;
}
void pl_drawmessage(Panel *p){
	pl_textmsg(p->b, pl_box(p->b, p->r, PASSIVE), font, ((Message *)p->data)->text);
}
int pl_hitmessage(Panel *g, Mouse *m){
	USED(g, m);
	return 0;
}
void pl_typemessage(Panel *g, Rune c){
	USED(g, c);
}
Point pl_getsizemessage(Panel *p, Point children){
	Message *mp;
	USED(children);
	mp=p->data;
	return pl_boxsize(pl_foldsize(font, mp->text, mp->minsize.x), PASSIVE);
}
void pl_childspacemessage(Panel *p, Point *ul, Point *size){
	USED(p, ul, size);
}
void plinitmessage(Panel *v, int flags, int wid, char *msg){
	Message *mp;
	mp=v->data;
	v->flags=flags|LEAF;
	v->draw=pl_drawmessage;
	v->hit=pl_hitmessage;
	v->type=pl_typemessage;
	v->getsize=pl_getsizemessage;
	v->childspace=pl_childspacemessage;
	mp->text=msg;
	mp->minsize=Pt(wid, font->height);
	v->kind="message";
}
Panel *plmessage(Panel *parent, int flags, int wid, char *msg){
	Panel *v;
	v=pl_newpanel(parent, sizeof(Message));
	plinitmessage(v, flags, wid, msg);
	return v;
}