void tkgeomchg(Tk *tk, TkGeom *g, int bd) { int w, h; void (*geomfn)(Tk*); if(memcmp(&tk->req, g, sizeof(TkGeom)) == 0 && bd == tk->borderwidth) return; geomfn = tkmethod[tk->type]->geom; if(geomfn != nil) geomfn(tk); if(tk->master != nil) { tkpackqit(tk->master); tkrunpack(tk->env->top); } else if(tk->geom != nil) { w = tk->req.width; h = tk->req.height; tk->req.width = 0; tk->req.height = 0; tk->geom(tk, tk->act.x, tk->act.y, w, h); if (tk->slave) { tkpackqit(tk); tkrunpack(tk->env->top); } } tkdeliver(tk, TkConfigure, g); }
static void tkcvswindsize(TkCitem *i) { Tk *s; int bw; Point p; TkGeom old; TkCwind *w; w = TKobj(TkCwind, i); s = w->sub; if(s == nil) return; if(w->width != s->act.width || w->height != s->act.height) { old = s->act; s->act.width = w->width; s->act.height = w->height; if(s->slave) { tkpackqit(s); tkrunpack(s->env->top); } tkdeliver(s, TkConfigure, &old); } p = tkcvsanchor(i->p.drawpt[0], s->act.width, s->act.height, w->flags); s->act.x = p.x; s->act.y = p.y; bw = 2*s->borderwidth; i->p.bb.min = p; i->p.bb.max.x = p.x + s->act.width + bw; i->p.bb.max.y = p.y + s->act.height + bw; }
char* tkpropagate(TkTop *t, char *arg) { Tk *tk; TkStab *s; char *buf; buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; arg = tkword(t, arg, buf, buf+Tkmaxitem, nil); tk = tklook(t, buf, 0); if(tk == nil) { tkerr(t, buf); free(buf); return TkBadwp; } tkword(t, arg, buf, buf+Tkmaxitem, nil); for(s = tkbool; s->val; s++) { if(strcmp(s->val, buf) == 0) { if(s->con == BoolT) { tk->flag &= ~Tknoprop; tkpackqit(tk); tkrunpack(t); } else tk->flag |= Tknoprop; free(buf); return nil; } } free(buf); return TkBadvl; }
static char* tkforget(TkTop *t, char *arg) { Tk *tk; char *buf; buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; for(;;) { arg = tkword(t, arg, buf, buf+Tkmaxitem, nil); if(buf[0] == '\0') break; tk = tklook(t, buf, 0); if(tk == nil) { tkrunpack(t); tkerr(t, buf); free(buf); return TkBadwp; } tkpackqit(tk->master); tkdelpack(tk); } free(buf); tkrunpack(t); return nil; }
void tksetslavereq(Tk *slave, TkGeom frame) { Point border; TkGeom pos, old; int slave2BW; void (*geomfn)(Tk*); border.x = slave->pad.x; border.y = slave->pad.y; slave2BW = slave->borderwidth * 2; pos.width = slave->req.width + slave2BW + slave->ipad.x; if((slave->flag&Tkfillx) || (pos.width > (frame.width - border.x))) pos.width = frame.width - border.x; pos.height = slave->req.height + slave2BW + slave->ipad.y; if((slave->flag&Tkfilly) || (pos.height > (frame.height - border.y))) pos.height = frame.height - border.y; border.x /= 2; border.y /= 2; if(slave->flag & Tknorth) pos.y = frame.y + border.y; else if(slave->flag & Tksouth) pos.y = frame.y + frame.height - pos.height - border.y; else pos.y = frame.y + (frame.height - pos.height)/2; if(slave->flag & Tkwest) pos.x = frame.x + border.x; else if(slave->flag & Tkeast) pos.x = frame.x + frame.width - pos.width - border.x; else pos.x = frame.x + (frame.width - pos.width)/2; pos.width -= slave2BW; pos.height -= slave2BW; if(memcmp(&slave->act, &pos, sizeof(TkGeom)) != 0) { old = slave->act; slave->act = pos; geomfn = tkmethod[slave->type]->geom; if(geomfn != nil) geomfn(slave); if(slave->slave) tkpackqit(slave); tkdeliver(slave, TkConfigure, &old); slave->dirty = tkrect(slave, 1); slave->flag |= Tkrefresh; } }
static int tkpacker(Tk *master) { Tk *slave; TkGeom frame, cavity, pos; int maxwidth, maxheight, tmp, slave2BW; pos.width = 0; pos.height = 0; maxwidth = 0; maxheight = 0; master->flag |= Tkrefresh; for (slave = master->slave; slave != nil; slave = slave->next) { slave2BW = slave->borderwidth*2; if(slave->flag & (Tktop|Tkbottom)) { tmp = slave->req.width + slave2BW + slave->pad.x + slave->ipad.x + pos.width; if(tmp > maxwidth) maxwidth = tmp; pos.height += slave->req.height + slave2BW + slave->pad.y + slave->ipad.y; } else { tmp = slave->req.height + slave2BW + slave->pad.y + slave->ipad.y + pos.height; if(tmp > maxheight) maxheight = tmp; pos.width += slave->req.width + slave2BW + + slave->pad.x + slave->ipad.x; } } if(pos.width > maxwidth) maxwidth = pos.width; if(pos.height > maxheight) maxheight = pos.height; if(maxwidth != master->req.width || maxheight != master->req.height) if((master->flag & Tknoprop) == 0) { if(master->geom != nil) { master->geom(master, master->act.x, master->act.y, maxwidth, maxheight); } else { master->req.width = maxwidth; master->req.height = maxheight; tkpackqit(master->master); } return 0; } cavity.x = 0; cavity.y = 0; pos.x = 0; pos.y = 0; cavity.width = master->act.width; cavity.height = master->act.height; for(slave = master->slave; slave != nil; slave = slave->next) { slave2BW = slave->borderwidth*2; if(slave->flag & (Tktop|Tkbottom)) { frame.width = cavity.width; frame.height = slave->req.height + slave2BW + slave->pad.y + slave->ipad.y; if(slave->flag & Tkexpand) frame.height += tkexpandy(slave, cavity.height); cavity.height -= frame.height; if(cavity.height < 0) { frame.height += cavity.height; cavity.height = 0; } frame.x = cavity.x; if(slave->flag & Tktop) { frame.y = cavity.y; cavity.y += frame.height; } else frame.y = cavity.y + cavity.height; } else { frame.height = cavity.height; frame.width = slave->req.width + slave2BW + slave->pad.x + slave->ipad.x; if(slave->flag & Tkexpand) frame.width += tkexpandx(slave, cavity.width); cavity.width -= frame.width; if(cavity.width < 0) { frame.width += cavity.width; cavity.width = 0; } frame.y = cavity.y; if(slave->flag & Tkleft) { frame.x = cavity.x; cavity.x += frame.width; } else frame.x = cavity.x + cavity.width; } tksetslavereq(slave, frame); } master->dirty = tkrect(master, 1); tkdirty(master); return 1; }
char* tkpack(TkTop *t, char *arg, char **val) { TkParam param = defparam; TkParam *p = ¶m; TkOptab tko[2]; Tk *tk, **l, *tkp; TkName *names, *n; char *e, *w, *buf; buf = mallocz(Tkminitem, 0); if(buf == nil) return TkNomem; w = tkword(t, arg, buf, buf+Tkminitem, nil); if(strcmp(buf, "forget") == 0) { e = tkforget(t, w); free(buf); return e; } if(strcmp(buf, "propagate") == 0) { e = tkpropagate(t, w); free(buf); return e; } if(strcmp(buf, "slaves") == 0) { e = tkslaves(t, w, val); free(buf); return e; } free(buf); tko[0].ptr = p; tko[0].optab = opts; tko[1].ptr = nil; names = nil; e = tkparse(t, arg, tko, &names); if(e != nil) return e; if((p->before && p->before->master == nil) || (p->after && p->after->master == nil)) { tkfreename(names); return TkNotpk; } for(n = names; n; n = n->link) { tkp = tklook(t, n->name, 0); if(tkp == nil) { tkerr(t, n->name); tkfreename(names); return TkBadwp; } if(tkp->flag & Tkwindow) { tkfreename(names); return TkIstop; } if(tkp->parent != nil) { tkfreename(names); return TkWpack; } n->obj = tkp; } e = nil; for(n = names; n; n = n->link) { tk = n->obj; if(tk->master == nil) { tk->pad = ZP; tk->ipad = ZP; tk->flag &= ~(Tkanchor|Tkside|Tkfill|Tkexpand); tk->flag |= Tktop; } if(tk->master != nil) { tkpackqit(tk->master); tkdelpack(tk); } if(p->before == nil && p->after == nil && p->in == nil) { tkp = tklook(t, n->name, 1); if(tkp == nil) { e = TkBadwp; tkerr(t, n->name); goto Error; } e = tkcanpack(tk, tkp); if (e != nil) goto Error; tkappendpack(tkp, tk, -1); } else { if(p->in != nil) { e = tkcanpack(tk, p->in); if(e != nil) goto Error; tkappendpack(p->in, tk, -1); } else if(p->before != nil) { e = tkcanpack(tk, p->before->master); if (e != nil) goto Error; tk->master = p->before->master; l = &tk->master->slave; for(;;) { if(*l == p->before) { tk->next = *l; *l = tk; break; } l = &(*l)->next; } p->before = tk; } else { e = tkcanpack(tk, p->after->master); if (e != nil) goto Error; tk->master = p->after->master; tk->next = p->after->next; p->after->next = tk; p->after = tk; } } tksetopt(p, tk); if (tk->master->flag&Tksubsub) tksetbits(tk, Tksubsub); tkpackqit(tk->master); } Error: tkfreename(names); tkrunpack(t); return e; }