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* 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* 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