7 int pl_max(int a, int b){
10 Point pl_sizesibs(Panel *p){
12 if(p==0) return Pt(0,0);
13 s=pl_sizesibs(p->next);
14 switch(p->flags&PACK){
17 s.x=pl_max(s.x, p->sizereq.x);
23 s.y=pl_max(s.y, p->sizereq.y);
29 * Compute the requested size of p and its descendants.
31 void pl_sizereq(Panel *p){
35 for(cp=p->child;cp;cp=cp->next){
37 if(cp->sizereq.x>maxsize.x) maxsize.x=cp->sizereq.x;
38 if(cp->sizereq.y>maxsize.y) maxsize.y=cp->sizereq.y;
40 for(cp=p->child;cp;cp=cp->next){
41 if(cp->flags&MAXX) cp->sizereq.x=maxsize.x;
42 if(cp->flags&MAXY) cp->sizereq.y=maxsize.y;
44 p->childreq=pl_sizesibs(p->child);
45 p->sizereq=addpt(addpt(p->getsize(p, p->childreq), p->ipad), p->pad);
46 if(p->flags&FIXEDX) p->sizereq.x=p->fixedsize.x;
47 if(p->flags&FIXEDY) p->sizereq.y=p->fixedsize.y;
49 Point pl_getshare(Panel *p){
51 if(p==0) return Pt(0,0);
52 share=pl_getshare(p->next);
53 if(p->flags&EXPAND) switch(p->flags&PACK){
56 if(share.x==0) share.x=1;
62 if(share.y==0) share.y=1;
68 * Set the sizes and rectangles of p and its descendants, given their requested sizes.
69 * Returns 1 if everything fit, 0 otherwise.
70 * For now we punt in the case that the children don't all fit.
71 * Possibly we should shrink all the children's sizereqs to fit,
72 * by the same means used to do EXPAND, except clamping at some minimum size,
73 * but that smacks of AI.
76 int pl_setrect(Panel *p, Point ul, Point avail){
77 Point space, newul, newspace, slack, share;
80 p->size=subpt(p->sizereq, p->pad);
81 ul=addpt(ul, divpt(p->pad, 2));
82 avail=subpt(avail, p->pad);
83 if(p->size.x>avail.x || p->size.y>avail.y){
85 return 0; /* not enough space! */
87 if(p->flags&(FILLX|EXPAND)) p->size.x=avail.x;
88 if(p->flags&(FILLY|EXPAND)) p->size.y=avail.y;
89 switch(p->flags&PLACE){
90 case PLACECEN: ul.x+=(avail.x-p->size.x)/2; ul.y+=(avail.y-p->size.y)/2; break;
91 case PLACES: ul.x+=(avail.x-p->size.x)/2; ul.y+= avail.y-p->size.y ; break;
92 case PLACEE: ul.x+= avail.x-p->size.x ; ul.y+=(avail.y-p->size.y)/2; break;
93 case PLACEW: ul.y+=(avail.y-p->size.y)/2; break;
94 case PLACEN: ul.x+=(avail.x-p->size.x)/2; break;
95 case PLACENE: ul.x+= avail.x-p->size.x ; break;
97 case PLACESE: ul.x+= avail.x-p->size.x ; ul.y+= avail.y-p->size.y ; break;
98 case PLACESW: ul.y+= avail.y-p->size.y ; break;
100 p->r=Rpt(ul, addpt(ul, p->size));
102 p->childspace(p, &ul, &space);
103 slack=subpt(space, p->childreq);
104 share=pl_getshare(p->child);
105 for(c=p->child;c;c=c->next){
107 switch(c->flags&PACK){
110 c->sizereq.x+=slack.x;
122 c->sizereq.y+=slack.y;
126 switch(c->flags&PACK){
128 newul=Pt(ul.x, ul.y+c->sizereq.y);
129 newspace=Pt(space.x, space.y-c->sizereq.y);
130 if(!pl_setrect(c, ul, Pt(space.x, c->sizereq.y))) return 0;
133 newul=Pt(ul.x+c->sizereq.x, ul.y);
134 newspace=Pt(space.x-c->sizereq.x, space.y);
135 if(!pl_setrect(c, ul, Pt(c->sizereq.x, space.y))) return 0;
139 newspace=Pt(space.x, space.y-c->sizereq.y);
140 if(!pl_setrect(c, Pt(ul.x, ul.y+space.y-c->sizereq.y),
141 Pt(space.x, c->sizereq.y))) return 0;
145 newspace=Pt(space.x-c->sizereq.x, space.y);
146 if(!pl_setrect(c, Pt(ul.x+space.x-c->sizereq.x, ul.y),
147 Pt(c->sizereq.x, space.y))) return 0;
155 int plpack(Panel *p, Rectangle where){
157 return pl_setrect(p, where.min, subpt(where.max, where.min));
160 * move an already-packed panel so that p->r=raddp(p->r, d)
162 void plmove(Panel *p, Point d){
163 if(strcmp(p->kind, "edit") == 0) /* sorry */
165 p->r=rectaddpt(p->r, d);
166 for(p=p->child;p;p=p->next) plmove(p, d);