📄 group.c
字号:
Control *c; c = _createctl(cs, "row", sizeof(Group), name); groupinit((Group*)c); c->setsize = groupsize; c->activate = activategroup; return c;}Control *createcolumn(Controlset *cs, char *name){ Control *c; c = _createctl(cs, "column", sizeof(Group), name); groupinit((Group*)c); c->setsize = groupsize; c->activate = activategroup; return c;}Control *createboxbox(Controlset *cs, char *name){ Control *c; c = _createctl(cs, "boxbox", sizeof(Group), name); groupinit((Group*)c); c->activate = activategroup; return c;}Control *createstack(Controlset *cs, char *name){ Control *c; c = _createctl(cs, "stack", sizeof(Group), name); groupinit((Group*)c); c->setsize = groupsize; return c;}void_ctladdgroup(Control *c, Control *q){ Group *g = (Group*)c; g->kids = ctlrealloc(g->kids, sizeof(Group*)*(g->nkids+1)); g->kids[g->nkids++] = q;}static voidremovegroup(Group *g, int n){ int i; if (g->selected == n) g->selected = -1; else if (g->selected > n) g->selected--; for (i = n+1; i < g->nkids; i++) g->kids[i-1] = g->kids[i]; g->nkids--;}static voidgroupsize(Control *c){ Rectangle r; int i; Control *q; Group *g; g = (Group*)c; assert(g->type == Ctlcolumn || g->type == Ctlrow || g->type == Ctlstack); if (g->mansize) return; r = Rect(1, 1, 1, 1); if (debug) fprint(2, "groupsize %q\n", g->name); for (i = 0; i < g->nkids; i++){ q = g->kids[i]; if (q->setsize) q->setsize(q); if (q->size.min.x == 0 || q->size.min.y == 0 || q->size.max.x == 0 || q->size.max.y == 0) ctlerror("%q: bad size %R", q->name, q->size); if (debug) fprint(2, "groupsize %q: [%d %q]: %R\n", g->name, i, q->name, q->size); switch(g->type){ case Ctlrow: if (i) r.min.x += q->size.min.x + g->border; else r.min.x = q->size.min.x; if (i) r.max.x += q->size.max.x + g->border; else r.max.x = q->size.max.x; if (r.min.y < q->size.min.y) r.min.y = q->size.min.y; if (r.max.y < q->size.max.y) r.max.y = q->size.max.y; break; case Ctlcolumn: if (r.min.x < q->size.min.x) r.min.x = q->size.min.x; if (r.max.x < q->size.max.x) r.max.x = q->size.max.x; if (i) r.min.y += q->size.min.y + g->border; else r.min.y = q->size.min.y; if (i) r.max.y += q->size.max.y + g->border; else r.max.y = q->size.max.y; break; case Ctlstack: if (r.min.x < q->size.min.x) r.min.x = q->size.min.x; if (r.max.x < q->size.max.x) r.max.x = q->size.max.x; if (r.min.y < q->size.min.y) r.min.y = q->size.min.y; if (r.max.y < q->size.max.y) r.max.y = q->size.max.y; break; } } g->size = rectaddpt(r, Pt(g->border, g->border)); if (debug) fprint(2, "groupsize %q: %R\n", g->name, g->size);}static voidboxboxresize(Group *g, Rectangle r){ int rows, cols, ht, wid, i, hpad, wpad; Rectangle rr; if(debug) fprint(2, "boxboxresize %q %R (%d×%d) min/max %R separation %d\n", g->name, r, Dx(r), Dy(r), g->size, g->separation); ht = 0; for(i=0; i<g->nkids; i++){ if (g->kids[i]->size.min.y > ht) ht = g->kids[i]->size.min.y; } if (ht == 0) ctlerror("boxboxresize: height"); rows = Dy(r) / (ht+g->separation); hpad = (Dy(r) % (ht+g->separation)) / g->nkids; cols = (g->nkids+rows-1)/rows; wid = Dx(r) / cols - g->separation; for(i=0; i<g->nkids; i++){ if (g->kids[i]->size.max.x < wid) wid = g->kids[i]->size.max.x; } for(i=0; i<g->nkids; i++){ if (g->kids[i]->size.min.x > wid) wid = g->kids[i]->size.min.x; } if (wid > Dx(r) / cols) ctlerror("can't fit controls in boxbox"); wpad = (Dx(r) % (wid+g->separation)) / g->nkids; rr = rectaddpt(Rect(0,0,wid, ht), addpt(r.min, Pt(g->separation/2, g->separation/2))); if(debug) fprint(2, "boxboxresize rows %d, cols %d, wid %d, ht %d, wpad %d, hpad %d\n", rows, cols, wid, ht, wpad, hpad); for(i=0; i<g->nkids; i++){ if(debug) fprint(2, " %d %q: %R (%d×%d)\n", i, g->kids[i]->name, rr, Dx(rr), Dy(rr)); _ctlprint(g->kids[i], "rect %R", rectaddpt(rr, Pt((wpad+wid+g->separation)*(i/rows), (hpad+ht+g->separation)*(i%rows)))); } g->nseparators = rows + cols - 2; g->separators = realloc(g->separators, g->nseparators*sizeof(Rectangle)); rr = r; rr.max.y = rr.min.y + g->separation+hpad; for (i = 1; i < rows; i++){ g->separators[i-1] = rectaddpt(rr, Pt(0, (hpad+ht+g->separation)*i-g->separation-hpad)); if(debug) fprint(2, "row separation %d [%d]: %R\n", i, i-1, rectaddpt(rr, Pt(0, (hpad+ht+g->separation)*i-g->separation))); } rr = r; rr.max.x = rr.min.x + g->separation+wpad; for (i = 1; i < cols; i++){ g->separators[i+rows-2] = rectaddpt(rr, Pt((wpad+wid+g->separation)*i-g->separation-wpad, 0)); if(debug) fprint(2, "col separation %d [%d]: %R\n", i, i+rows-2, rectaddpt(rr, Pt((wpad+wid+g->separation)*i-g->separation, 0))); }}static voidcolumnresize(Group *g, Rectangle r){ int x, y, *d, *p, i, j, t; Rectangle rr; Control *q; x = Dx(r); y = Dy(r); if(debug) fprint(2, "columnresize %q %R (%d×%d) min/max %R separation %d\n", g->name, r, Dx(r), Dy(r), g->size, g->separation); if (x < g->size.min.x) { werrstr("resize %s: too narrow: need %d, have %d", g->name, g->size.min.x, x); r.max.x = r.min.x + g->size.min.x; } if (y < g->size.min.y) { werrstr("resize %s: too short: need %d, have %d", g->name, g->size.min.y, y); r.max.y = r.min.y + g->size.min.y; y = Dy(r); } d = ctlmalloc(g->nkids*sizeof(int)); p = ctlmalloc(g->nkids*sizeof(int)); if(debug) fprint(2, "kiddies: "); for (i = 0; i < g->nkids; i++) { q = g->kids[i]; if(debug) fprint(2, "[%q]: %d⋯%d\t", q->name, q->size.min.y, q->size.max.y); d[i] = q->size.min.y; y -= d[i]; p[i] = q->size.max.y - q->size.min.y; } if(debug) fprint(2, "\n"); y -= (g->nkids-1) * g->separation; if(y < 0){ if (debug) fprint(2, "columnresize: y == %d\n", y); y = 0; } if (y >= g->size.max.y - g->size.min.y) { // all rects can be maximum width for (i = 0; i < g->nkids; i++) d[i] += p[i]; y -= g->size.max.y - g->size.min.y; } else { // rects can't be max width, divide up the rest j = y; for (i = 0; i < g->nkids; i++) { t = p[i] * y/(g->size.max.y - g->size.min.y); d[i] += t; j -= t; } d[0] += j; y = 0; } g->nseparators = g->nkids-1; g->separators = realloc(g->separators, g->nseparators*sizeof(Rectangle)); j = 0; rr = r; for (i = 0; i < g->nkids; i++) { q = g->kids[i]; if (i < g->nkids - 1){ g->separators[i].min.x = r.min.x; g->separators[i].max.x = r.max.x; } t = y / (g->nkids - i); y -= t; j += t/2; rr.min.y = r.min.y + j; if (i) g->separators[i-1].max.y = rr.min.y; j += d[i]; rr.max.y = r.min.y + j; if (i < g->nkids - 1) g->separators[i].min.y = rr.max.y; j += g->separation + t - t/2; _ctlprint(q, "rect %R", rr); if(debug) fprint(2, " %d %q: %R (%d×%d)\n", i, q->name, rr, Dx(rr), Dy(rr)); } free(d); free(p);}static voidrowresize(Group *g, Rectangle r){ int x, y, *d, *p, i, j, t; Rectangle rr; Control *q; x = Dx(r); y = Dy(r); if(debug) fprint(2, "rowresize %q %R (%d×%d), separation %d\n", g->name, r, Dx(r), Dy(r), g->separation); if (x < g->size.min.x) { werrstr("resize %s: too narrow: need %d, have %d", g->name, g->size.min.x, x); r.max.x = r.min.x + g->size.min.x; x = Dx(r); } if (y < g->size.min.y) { werrstr("resize %s: too short: need %d, have %d", g->name, g->size.min.y, y); r.max.y = r.min.y + g->size.min.y; } d = ctlmalloc(g->nkids*sizeof(int)); p = ctlmalloc(g->nkids*sizeof(int)); if(debug) fprint(2, "kiddies: "); for (i = 0; i < g->nkids; i++) { q = g->kids[i]; if(debug) fprint(2, "[%q]: %d⋯%d\t", q->name, q->size.min.x, q->size.max.x); d[i] = q->size.min.x; x -= d[i]; p[i] = q->size.max.x - q->size.min.x; } if(debug) fprint(2, "\n"); x -= (g->nkids-1) * g->separation; if(x < 0){ if (debug) fprint(2, "rowresize: x == %d\n", x); x = 0; } if (x >= g->size.max.x - g->size.min.x) { if (debug) fprint(2, "max: %d > %d - %d", x, g->size.max.x, g->size.min.x); // all rects can be maximum width for (i = 0; i < g->nkids; i++) d[i] += p[i]; x -= g->size.max.x - g->size.min.x; } else { if (debug) fprint(2, "divvie up: %d < %d - %d", x, g->size.max.x, g->size.min.x); // rects can't be max width, divide up the rest j = x; for (i = 0; i < g->nkids; i++) { t = p[i] * x/(g->size.max.x - g->size.min.x); d[i] += t; j -= t; } d[0] += j; x = 0; } j = 0; g->nseparators = g->nkids-1; g->separators = realloc(g->separators, g->nseparators*sizeof(Rectangle)); rr = r; for (i = 0; i < g->nkids; i++) { q = g->kids[i]; if (i < g->nkids - 1){ g->separators[i].min.y = r.min.y; g->separators[i].max.y = r.max.y; } t = x / (g->nkids - i); x -= t; j += t/2; rr.min.x = r.min.x + j; if (i) g->separators[i-1].max.x = rr.min.x; j += d[i]; rr.max.x = r.min.x + j; if (i < g->nkids - 1) g->separators[i].min.x = rr.max.x; j += g->separation + t - t/2; _ctlprint(q, "rect %R", rr); if(debug) fprint(2, " %d %q: %R (%d×%d)\n", i, q->name, rr, Dx(rr), Dy(rr)); } free(d); free(p);}static voidstackresize(Group *g, Rectangle r){ int x, y, i; Control *q; x = Dx(r); y = Dy(r); if(debug) fprint(2, "stackresize %q %R (%d×%d)\n", g->name, r, Dx(r), Dy(r)); if (x < g->size.min.x){ werrstr("resize %s: too narrow: need %d, have %d", g->name, g->size.min.x, x); return; } if (y < g->size.min.y){ werrstr("resize %s: too short: need %d, have %d", g->name, g->size.min.y, y); return; } if (x > g->size.max.x) { x = (x - g->size.max.x)/2; r.min.x += x; r.max.x -= x; } if (y > g->size.max.y) { y = (y - g->size.max.y)/2; r.min.y += y; r.max.y -= y; } for (i = 0; i < g->nkids; i++){ q = g->kids[i]; if(debug) fprint(2, " %d %q: %R (%d×%d)\n", i, q->name, r, Dx(r), Dy(r)); } for (i = 0; i < g->nkids; i++){ q = g->kids[i]; _ctlprint(q, "rect %R", r); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -