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