1082 lines · 18.9 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <draw.h>#include <memdraw.h>#include <thread.h>#include <cursor.h>#include <mouse.h>#include <keyboard.h>#include <frame.h>#include <plumb.h>#include <html.h>#include "dat.h"#include "fns.h" static void sizeitem(Lay *, Item *); staticvoidsizetext(Lay *lay, Itext *i){	lay->font = getfont(i->fnt);	i->height = lay->font->height + 2*Space;	i->width = runestringwidth(lay->font, i->s);	i->width += runestringnwidth(lay->font, L" ", 1);} staticvoidsizerule(Lay *lay, Irule *i){	i->width = lay->width;	i->height = Space + i->size + Space;} staticvoidsizeimage(Lay *, Iimage *i){	Cimage *ci; 	ci = (Cimage *)i->aux; 	if(ci==nil)		return; 	if(ci->i == nil)		getimage(ci, i->altrep);	if(ci->i == nil)		return;	i->width = Dx(ci->i->r) + i->border + i->hspace;	i->height = Dy(ci->i->r) + i->border + i->vspace;} staticvoidsizetextfield(Lay *, Iformfield *i){	Formfield *ff;	Font *f;	int w, h; 	ff = i->formfield;	if(ff->ftype == Ftextarea){		w = ff->cols;		h = ff->rows;	}else{		w = ff->size;		h = 1;	}	f = getfont(WFont);	i->width = runestringnwidth(f, L"0", 1)*w + 2*(Space+Border+Margin);	i->width += Scrollsize+Scrollgap;	i->height = f->height*h + 2*(Space+Border+Margin);} staticvoidsizecheck(Lay *, Iformfield *i){	i->width = Boxsize + Space;	i->height = Boxsize;} staticvoidsizebutton(Lay *, Iformfield *i){	Font *f;	int x; 	x = Margin + Border + Space;	f = getfont(WFont);	i->width = runestringwidth(f, i->formfield->value) + 2*x + Space;	i->height = f->height + 2*x;} staticvoidsizefimage(Lay *lay, Iformfield *i){	Iimage *ii; 	ii = (Iimage *)i->formfield->image;	sizeimage(lay, ii);	i->width = ii->width;	i->height = ii->height;} staticvoidsizeselect(Lay *, Iformfield *i){	Option *o;	Font *f;	int x; 	f = getfont(WFont);	i->width = 0;	for(o=i->formfield->options; o!=nil; o=o->next)		i->width = max(i->width, runestringwidth(f, o->display));	x = Margin + Border + Space;	i->width += 2*x;	i->height = f->height+2*x;} staticvoidsizeformfield(Lay *lay, Iformfield *i){	int type; 	type = i->formfield->ftype; 	if(type==Ftext || type==Ftextarea || type==Fpassword)		sizetextfield(lay, i);	else if(type==Fcheckbox || type==Fradio)		sizecheck(lay, i);	else if(type==Fbutton || type==Freset || type==Fsubmit)		sizebutton(lay, i);	else if(type == Fimage)		sizefimage(lay, i);	else if(type == Fselect)		sizeselect(lay, i);} staticvoidsizetable(Lay *lay, Itable *i){	tablesize(i->table, lay->width);	i->width = i->table->totw;	i->height = i->table->toth;} staticvoidsizefloat(Lay *lay, Ifloat *i){	sizeitem(lay, i->item);	i->width = i->item->width;	i->height = i->item->height;} staticvoidsizespacer(Lay *lay, Ispacer *i){	if(i->spkind != ISPnull){		if(i->spkind == ISPhspace)			i->width = stringnwidth(lay->font, " ", 1);		i->height = lay->font->height + 2*Space;	}} staticvoidsizeitem(Lay *lay, Item *i){ 	switch(i->tag){	case Itexttag:		sizetext(lay, (Itext *)i);		break;	case Iruletag:		sizerule(lay, (Irule *)i);		break;	case Iimagetag:		sizeimage(lay, (Iimage *)i);		break;	case Iformfieldtag:		sizeformfield(lay, (Iformfield *)i);		break;	case Itabletag:		sizetable(lay, (Itable *)i);		break;	case Ifloattag:		sizefloat(lay, (Ifloat *)i);		break;	case Ispacertag:		sizespacer(lay, (Ispacer *)i);		break;	default:		error("can't happen");	}} staticvoiddrawtext(Box *b, Page *p, Image *im){	Rectangle r, r1;	Image *c;	Point pt;	Font *f;	Itext *i;	int q0, q1; 	r = rectsubpt(b->r, p->pos);	i = (Itext *)b->i;	f = getfont(i->fnt);	if(istextsel(p, b->r, &q0, &q1, i->s, f)){		r1 = r;		if(q0 > 0)			r1.min.x += runestringnwidth(f, i->s, q0);		if(q1 > 0)			r1.max.x = r1.min.x + runestringnwidth(f, i->s+q0, q1-q0);		draw(im, r1, textcols[HIGH], nil, ZP);	}	c = getcolor(i->fg);	runestringbg(im, r.min, c, ZP, f, i->s, im, addpt(r.min, im->r.min)); 	if(i->ul == ULnone)		return; 	if(i->ul == ULmid)		r.min.y += f->height/2;	else		r.min.y +=f->height-1;	pt = r.min;	pt.x +=  runestringwidth(f, i->s);	line(im, r.min, pt, Enddisc, Enddisc, 0, c, ZP);} staticvoiddrawrule(Box *b, Page *p, Image *im){	Rectangle r;	Irule *i; 	i = ((Irule *)b->i);	r = rectsubpt(b->r, p->pos);	r.min.y += Space;	r.max.y -=Space;	draw(im, r, getcolor(i->color), nil, ZP);} staticvoiddrawimage(Box *b, Page *p, Image *im){	Rectangle r;	Cimage *ci;	Iimage *i;	Image *c; 	if(b->i->tag==Iimagetag)		i = (Iimage *)b->i;	else		i = (Iimage *)((Iformfield *)b->i)->formfield->image; 	ci = (Cimage *)i->aux;	if(ci==nil || ci->i==nil)		return; 	r = rectsubpt(b->r, p->pos);	r.min.x += i->border + i->hspace;	r.min.y += i->border + i->vspace;	r.max.x -= i->border + i->hspace;	r.max.y -= i->border + i->vspace; 	draw(im, r,  ci->i, nil, ci->i->r.min); 	if(i->border){		if(i->anchorid >= 0)			c = getcolor(p->doc->link);		else			c = display->black; 		border(im, r, i->border, c, ZP);	}} staticvoiddrawtextfield(Image *im, Rectangle r, Iformfield *i){	Formfield *ff;	Image *c[3];	Text *t;	Font *f; 	r = insetrect(r, Space);	colarray(c, getcolor(Dark), getcolor(Light), display->white, 1);	rect3d(im, r, Border, c, ZP);	r = insetrect(r, Border+Margin); 	if(i->aux == nil){		ff = i->formfield;		t = emalloc(sizeof(Text));		if(ff->ftype == Ftextarea)			t->what = Textarea;		else			t->what = Entry;		if(ff->ftype == Fpassword)			f = passfont;		else			f = getfont(WFont);		textinit(t, im, r, f, textcols);		if(ff->value!=nil){			textinsert(t, 0, ff->value, runestrlen(ff->value));			textsetselect(t, t->rs.nr, t->rs.nr);		}		if(t->what == Textarea)			textscrdraw(t);		i->aux = t;	}else		textresize(i->aux, im, r);} voiddrawcheck(Image *im, Rectangle r, Formfield *f){	Image *c[3];	Point pt;	int n; 	if(f->flags & FFchecked)		colarray(c, getcolor(Dark), getcolor(Light), getcolor(Red), TRUE);	else		colarray(c, getcolor(Dark), getcolor(Light), getcolor(Back), FALSE); 	if(f->ftype == Fradio){		n = Boxsize/2-1;		pt = addpt(r.min, Pt(n,n));		ellipse3d(im, pt, n, Border, c, ZP);	}else		rect3d(im, r, Border, c, ZP);} voiddrawbutton(Image *im, Rectangle r, Formfield *f, int checked){	Image *c[3]; 	r = insetrect(r, Space);	colarray(c, getcolor(Dark), getcolor(Light), getcolor(Back), checked);	rect3d(im, r, Border, c, ZP);	r.min.x += Border + Margin;	r.min.y += Border + Margin;	runestringbg(im, r.min, display->black, ZP,  getfont(WFont), f->value, c[2], ZP);} voiddrawselect(Image *im, Rectangle r,	Iformfield *i){	Formfield *f;	Image *c[3]; 	f = i->formfield;	if(f->options == nil)		return;	r = insetrect(r, Space);	colarray(c, getcolor(Dark), getcolor(Light), display->white, 1);	rect3d(im, r, Border, c, ZP);	r = insetrect(r, Border+Margin);	draw(im, r, textcols[HIGH], nil, ZP);	if(i->aux==nil){		i->aux = f->options->display;		i->formfield->value = erunestrdup(f->options->value);	}	runestring(im, r.min, display->black, ZP,  getfont(WFont), i->aux);} /* Formfields are a special case */staticvoiddrawformfield(Box *b, Page *p, Image *im){	Formfield *f;	int type; 	f = ((Iformfield *)b->i)->formfield;	type =f->ftype;	if(istextfield(b->i))		drawtextfield(im, rectsubpt(b->r, p->pos), (Iformfield *)b->i);	else if(type==Fcheckbox || type==Fradio)		drawcheck(im, rectsubpt(b->r, p->pos), f);	else if(type==Fbutton || type==Freset || type==Fsubmit)		drawbutton(im, rectsubpt(b->r, p->pos), f, FALSE);	else if(type == Fimage)		drawimage(b, p, im);	else if(type == Fselect)		drawselect(im, rectsubpt(b->r, p->pos), (Iformfield *)b->i);} staticvoiddrawnull(Box *, Page *, Image *){} staticPage *whichtarget1(Page *p, Rune *r){	Kidinfo *k;	Page *c, *ret; 	k = p->kidinfo;	if(k && k->name && runestrcmp(k->name, r)==0)		return p;	for(c=p->child; c; c=c->next){		ret = whichtarget1(c, r);		if(ret)			return ret;	}	return nil;} staticPage *whichtarget(Page *p, int t){	Page *r; 	switch(t){	case FTblank:	case FTtop:		r = &p->w->page;		break;	case FTself:		r = p;		break;	case FTparent:		r = p->parent;		break;	default:		if(targetname(t) == L"?")			error("targetname");		r = whichtarget1(&p->w->page, targetname(t));	} 	return r ? r: &p->w->page;} staticvoidmouselink(Box *b, Page *p, int but){	Runestr rs;	Anchor *a;	Rune *base; 	/* eat mouse */	while(mousectl->buttons)		readmouse(mousectl); 	if(b->i->anchorid < 0)		return; 	/* binary search would be better */	for(a=p->doc->anchors; a!=nil; a=a->next)		if(a->index == b->i->anchorid)			break; 	if(a==nil || a->href==nil)		return; 	base = p->doc->base;	p = whichtarget(p, a->target);	rs.r = nil;	if(a->href)		rs.r = urlcombine(base, a->href);	if(rs.r == nil)		return;	rs.nr = runestrlen(rs.r); 	if(but == 1)		pageget(p, &rs, nil, HGet, p==&p->w->page);	else if(but == 2)		textset(&p->w->status, rs.r, rs.nr);	else if(but == 4)		plumbrunestr(&rs, nil);	closerunestr(&rs);} static voidsubmit(Page *p, Formfield *formfield, int subfl){

Lines 1–500 of 1082.