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