xref: /inferno-os/libprefab/box.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth #include <lib9.h>
2*37da2899SCharles.Forsyth #include <draw.h>
3*37da2899SCharles.Forsyth #include <interp.h>
4*37da2899SCharles.Forsyth #include <isa.h>
5*37da2899SCharles.Forsyth #include "../libinterp/runt.h"
6*37da2899SCharles.Forsyth #include <drawif.h>
7*37da2899SCharles.Forsyth #include <prefab.h>
8*37da2899SCharles.Forsyth 
9*37da2899SCharles.Forsyth PCompound*
box(Prefab_Environ * e,Draw_Point p,Prefab_Element * title,Prefab_Element * list)10*37da2899SCharles.Forsyth box(Prefab_Environ *e, Draw_Point p, Prefab_Element *title, Prefab_Element *list)
11*37da2899SCharles.Forsyth {
12*37da2899SCharles.Forsyth 	Draw_Rect er, r, lr;
13*37da2899SCharles.Forsyth 	PCompound *pc;
14*37da2899SCharles.Forsyth 	Prefab_Compound *c;
15*37da2899SCharles.Forsyth 	Image *disp;
16*37da2899SCharles.Forsyth 	Draw_Image *ddisp;
17*37da2899SCharles.Forsyth 	Screen *screen;
18*37da2899SCharles.Forsyth 	Heap *h;
19*37da2899SCharles.Forsyth 	Point pt;
20*37da2899SCharles.Forsyth 	int w;
21*37da2899SCharles.Forsyth 
22*37da2899SCharles.Forsyth 	if(list == H)
23*37da2899SCharles.Forsyth 		return H;
24*37da2899SCharles.Forsyth 	screen = lookupscreen(e->screen);
25*37da2899SCharles.Forsyth 	if(screen == nil)
26*37da2899SCharles.Forsyth 		return H;
27*37da2899SCharles.Forsyth 	h = heapz(TCompound);
28*37da2899SCharles.Forsyth 	if(h == H)
29*37da2899SCharles.Forsyth 		return H;
30*37da2899SCharles.Forsyth 	pc = H2D(PCompound*, h);
31*37da2899SCharles.Forsyth 	c = &pc->c;
32*37da2899SCharles.Forsyth 
33*37da2899SCharles.Forsyth 	gchalt++;
34*37da2899SCharles.Forsyth 	r = list->r;
35*37da2899SCharles.Forsyth 	if(title != H){
36*37da2899SCharles.Forsyth 		w = 2+1+3+Dx(title->r)+1;
37*37da2899SCharles.Forsyth 		if(w > Dx(r))
38*37da2899SCharles.Forsyth 			r.max.x = r.min.x + w;
39*37da2899SCharles.Forsyth 		r.max.y += 2+1+Dy(title->r)+1;
40*37da2899SCharles.Forsyth 	}
41*37da2899SCharles.Forsyth 
42*37da2899SCharles.Forsyth 	er = edgerect(e, p, &r);
43*37da2899SCharles.Forsyth 
44*37da2899SCharles.Forsyth 	disp = allocwindow(screen, IRECT(er), Refbackup /*refreshcompound*/, DWhite);
45*37da2899SCharles.Forsyth 	if(disp == nil){
46*37da2899SCharles.Forsyth    Err:
47*37da2899SCharles.Forsyth 		destroy(c);
48*37da2899SCharles.Forsyth 		gchalt--;
49*37da2899SCharles.Forsyth 		return H;
50*37da2899SCharles.Forsyth 	}
51*37da2899SCharles.Forsyth 	if((ddisp=mkdrawimage(disp, e->screen, e->screen->display, nil)) == H){
52*37da2899SCharles.Forsyth 		freeimage(disp);
53*37da2899SCharles.Forsyth 		goto Err;
54*37da2899SCharles.Forsyth 	}
55*37da2899SCharles.Forsyth 
56*37da2899SCharles.Forsyth 	lr = r;
57*37da2899SCharles.Forsyth 	if(title != H){
58*37da2899SCharles.Forsyth 		pt.x = r.min.x+3;
59*37da2899SCharles.Forsyth 		pt.y = r.min.y+3;
60*37da2899SCharles.Forsyth 		translateelement(title, pt);
61*37da2899SCharles.Forsyth 		lr.min.y = title->r.max.y+1;
62*37da2899SCharles.Forsyth 	}
63*37da2899SCharles.Forsyth 	translateelement(list, subpt(IPOINT(lr.min), IPOINT(list->r.min)));
64*37da2899SCharles.Forsyth 
65*37da2899SCharles.Forsyth 	c->r = r;
66*37da2899SCharles.Forsyth 	c->image = ddisp;
67*37da2899SCharles.Forsyth 	c->environ = e;
68*37da2899SCharles.Forsyth 	D2H(e)->ref++;
69*37da2899SCharles.Forsyth 	if(title != H){
70*37da2899SCharles.Forsyth 		c->title = title;
71*37da2899SCharles.Forsyth 		D2H(title)->ref++;
72*37da2899SCharles.Forsyth 	}
73*37da2899SCharles.Forsyth 	if(list != H){
74*37da2899SCharles.Forsyth 		c->contents = (Prefab_Element*)list;
75*37da2899SCharles.Forsyth 		D2H(list)->ref++;
76*37da2899SCharles.Forsyth 	}
77*37da2899SCharles.Forsyth 	pc->display = screen->display;
78*37da2899SCharles.Forsyth 	gchalt--;
79*37da2899SCharles.Forsyth 	return pc;
80*37da2899SCharles.Forsyth }
81