⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 group.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -