xref: /inferno-os/libprefab/textbox.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*
layoutbox(Prefab_Environ * e,Draw_Rect rr,String * titletext,List * texttext)10*37da2899SCharles.Forsyth layoutbox(Prefab_Environ *e, Draw_Rect rr, String *titletext, List *texttext)
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 	PElement *title, *text;
16*37da2899SCharles.Forsyth 	Image *disp;
17*37da2899SCharles.Forsyth 	Draw_Image *ddisp;
18*37da2899SCharles.Forsyth 	Screen *screen;
19*37da2899SCharles.Forsyth 	Heap *h;
20*37da2899SCharles.Forsyth 	Rectangle t;
21*37da2899SCharles.Forsyth 	int wid, w;
22*37da2899SCharles.Forsyth 	Point p, pt;
23*37da2899SCharles.Forsyth 
24*37da2899SCharles.Forsyth 	screen = lookupscreen(e->screen);
25*37da2899SCharles.Forsyth 	if(screen == nil)
26*37da2899SCharles.Forsyth 		return H;
27*37da2899SCharles.Forsyth 
28*37da2899SCharles.Forsyth 	gchalt++;
29*37da2899SCharles.Forsyth 	wid = Dx(rr);
30*37da2899SCharles.Forsyth 	P2P(p, rr.min);
31*37da2899SCharles.Forsyth 	title = H;
32*37da2899SCharles.Forsyth 	text = H;
33*37da2899SCharles.Forsyth 	if(texttext != H){
34*37da2899SCharles.Forsyth 		er.min.x = 0;
35*37da2899SCharles.Forsyth 		er.min.y = 0;
36*37da2899SCharles.Forsyth 		er.max.x = wid-5;
37*37da2899SCharles.Forsyth 		er.max.y = Dy(rr);
38*37da2899SCharles.Forsyth 		text = layoutelement(e, texttext, er, EText);
39*37da2899SCharles.Forsyth 		if(text == H){
40*37da2899SCharles.Forsyth 			gchalt--;
41*37da2899SCharles.Forsyth 			return H;
42*37da2899SCharles.Forsyth 		}
43*37da2899SCharles.Forsyth 		if(wid <= 0)
44*37da2899SCharles.Forsyth 			wid = Dx(text->e.r)+5;
45*37da2899SCharles.Forsyth 	}
46*37da2899SCharles.Forsyth 	if(titletext != H){
47*37da2899SCharles.Forsyth 		/* see how wide title wants to be */
48*37da2899SCharles.Forsyth 		memset(&er, 0, sizeof er);
49*37da2899SCharles.Forsyth 		title = textelement(e, titletext, er, ETitle);
50*37da2899SCharles.Forsyth 		if(title == H){
51*37da2899SCharles.Forsyth     Errtitle:
52*37da2899SCharles.Forsyth 			destroy(text);
53*37da2899SCharles.Forsyth 			gchalt--;
54*37da2899SCharles.Forsyth 			return H;
55*37da2899SCharles.Forsyth 		}
56*37da2899SCharles.Forsyth 		w = 2+1+3+Dx(title->e.r)+1;
57*37da2899SCharles.Forsyth 		/* if title is wider than text, adjust wid accordingly */
58*37da2899SCharles.Forsyth 		if(text!=0 && Dx(text->e.r)<w){
59*37da2899SCharles.Forsyth 			if(Dx(text->e.r) < 100){	/* narrow text; don't let title get too wide */
60*37da2899SCharles.Forsyth 				if(w > 250+5)
61*37da2899SCharles.Forsyth 					w = 250+5;
62*37da2899SCharles.Forsyth 				wid = w;
63*37da2899SCharles.Forsyth 			}
64*37da2899SCharles.Forsyth 			destroy(title);
65*37da2899SCharles.Forsyth 			er.min.x = 0;
66*37da2899SCharles.Forsyth 			er.min.y = 0;
67*37da2899SCharles.Forsyth 			er.max.x = wid-5;
68*37da2899SCharles.Forsyth 			er.max.y = 0;
69*37da2899SCharles.Forsyth 			title = textelement(e, titletext, er, ETitle);
70*37da2899SCharles.Forsyth 			if(title == H)
71*37da2899SCharles.Forsyth 				goto Errtitle;
72*37da2899SCharles.Forsyth 		}
73*37da2899SCharles.Forsyth 		if(wid <= 0)
74*37da2899SCharles.Forsyth 			wid = Dx(title->e.r)+5;
75*37da2899SCharles.Forsyth 	}
76*37da2899SCharles.Forsyth 
77*37da2899SCharles.Forsyth 	h = heapz(TCompound);
78*37da2899SCharles.Forsyth 	pc = H2D(PCompound*, h);
79*37da2899SCharles.Forsyth 	c = &pc->c;
80*37da2899SCharles.Forsyth 	c->title = (Prefab_Element*)title;
81*37da2899SCharles.Forsyth 	c->contents = (Prefab_Element*)text;
82*37da2899SCharles.Forsyth 	/* now can just destroy c to clean up */
83*37da2899SCharles.Forsyth 
84*37da2899SCharles.Forsyth 	r.min = DPOINT(p);
85*37da2899SCharles.Forsyth 	r.max.x = r.min.x+wid;
86*37da2899SCharles.Forsyth 	r.max.y = p.y+2+1 + 1+1;
87*37da2899SCharles.Forsyth 	if(title != H)
88*37da2899SCharles.Forsyth 		r.max.y += title->nkids*e->style->titlefont->height+1;
89*37da2899SCharles.Forsyth 	if(text != H)
90*37da2899SCharles.Forsyth 		r.max.y += Dy(text->e.r);
91*37da2899SCharles.Forsyth 
92*37da2899SCharles.Forsyth 	er = edgerect(e, DPOINT(p), &r);
93*37da2899SCharles.Forsyth 
94*37da2899SCharles.Forsyth 	R2R(t, er);
95*37da2899SCharles.Forsyth 	disp = allocwindow(screen, t, Refbackup /*refreshcompound*/, DWhite);
96*37da2899SCharles.Forsyth 	if(disp == nil){
97*37da2899SCharles.Forsyth     Err:
98*37da2899SCharles.Forsyth 		destroy(c);
99*37da2899SCharles.Forsyth 		gchalt--;
100*37da2899SCharles.Forsyth 		return H;
101*37da2899SCharles.Forsyth 	}
102*37da2899SCharles.Forsyth 	if((ddisp=mkdrawimage(disp, e->screen, e->screen->display, nil)) == H){
103*37da2899SCharles.Forsyth 		freeimage(disp);
104*37da2899SCharles.Forsyth 		goto Err;
105*37da2899SCharles.Forsyth 	}
106*37da2899SCharles.Forsyth 
107*37da2899SCharles.Forsyth 	lr = r;
108*37da2899SCharles.Forsyth 	if(title != H){
109*37da2899SCharles.Forsyth 		pt.x = r.min.x+3;
110*37da2899SCharles.Forsyth 		pt.y = r.min.y+3;
111*37da2899SCharles.Forsyth 		translateelement(&title->e, pt);
112*37da2899SCharles.Forsyth 		lr.min.y = title->e.r.max.y+1;
113*37da2899SCharles.Forsyth 	}
114*37da2899SCharles.Forsyth 
115*37da2899SCharles.Forsyth 	if(text != H)
116*37da2899SCharles.Forsyth 		translateelement((Prefab_Element*)text, subpt(IPOINT(lr.min), IPOINT(text->e.r.min)));
117*37da2899SCharles.Forsyth 
118*37da2899SCharles.Forsyth 	c->r = r;
119*37da2899SCharles.Forsyth 	c->environ = e;
120*37da2899SCharles.Forsyth 	c->image = ddisp;
121*37da2899SCharles.Forsyth 	D2H(e)->ref++;
122*37da2899SCharles.Forsyth 	pc->display = screen->display;
123*37da2899SCharles.Forsyth 	gchalt--;
124*37da2899SCharles.Forsyth 	return pc;
125*37da2899SCharles.Forsyth 
126*37da2899SCharles.Forsyth }
127*37da2899SCharles.Forsyth 
128*37da2899SCharles.Forsyth PCompound*
textbox(Prefab_Environ * e,Draw_Rect rr,String * titletext,String * texttext)129*37da2899SCharles.Forsyth textbox(Prefab_Environ *e, Draw_Rect rr, String *titletext, String *texttext)
130*37da2899SCharles.Forsyth {
131*37da2899SCharles.Forsyth 	PCompound *pc;
132*37da2899SCharles.Forsyth 	List *l;
133*37da2899SCharles.Forsyth 
134*37da2899SCharles.Forsyth 	l = listoflayout(e->style, texttext, EText);
135*37da2899SCharles.Forsyth 	pc = layoutbox(e, rr, titletext, l);
136*37da2899SCharles.Forsyth 	free(l);
137*37da2899SCharles.Forsyth 	return pc;
138*37da2899SCharles.Forsyth }
139