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

📄 group.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <u.h>#include <libc.h>#include <thread.h>#include <draw.h>#include <mouse.h>#include <keyboard.h>#include <control.h>#include "group.h"static int debug = 0;static int debugm = 0;static int debugr = 0;enum{	EAdd,	EBorder,	EBordercolor,	EFocus,	EHide,	EImage,	ERect,	ERemove,	EReveal,	ESeparation,	EShow,	ESize,};static char *cmds[] = {	[EAdd] =			"add",	[EBorder] =		"border",	[EBordercolor] =	"bordercolor",	[EFocus] = 		"focus",	[EHide] =			"hide",	[EImage] =		"image",	[ERect] =			"rect",	[ERemove] =		"remove",	[EReveal] =		"reveal",	[ESeparation] =		"separation",	[EShow] =			"show",	[ESize] =			"size",};static void		boxboxresize(Group*, Rectangle);static void		columnresize(Group*, Rectangle);static void		groupctl(Control *c, CParse *cp);static void		groupfree(Control*);static void		groupmouse(Control *, Mouse *);static void		groupsize(Control *c);static void		removegroup(Group*, int);static void		rowresize(Group*, Rectangle);static void		stackresize(Group*, Rectangle);static voidgroupinit(Group *g){	g->bordercolor = _getctlimage("black");	g->image = _getctlimage("white");	g->border = 0;	g->mansize = 0;	g->separation = 0;	g->selected = -1;	g->lastkid = -1;	g->kids = nil;	g->separators = nil;	g->nkids = 0;	g->nseparators = 0;	g->ctl = groupctl;	g->mouse = groupmouse;	g->exit = groupfree;}static voidgroupctl(Control *c, CParse *cp){	int cmd, i, n;		Rectangle r;	Group *g;	g = (Group*)c;	cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));	switch(cmd){	case EAdd:		for (i = 1; i < cp->nargs; i++){			c = controlcalled(cp->args[i]);			if (c == nil)				ctlerror("%q: no such control: %s", g->name, cp->args[i]);			_ctladdgroup(g, c);		}		if (g->setsize)			g->setsize((Control*)g);		break;	case EBorder:		_ctlargcount(g, cp, 2);		if(cp->iargs[1] < 0)			ctlerror("%q: bad border: %c", g->name, cp->str);		g->border = cp->iargs[1];		break;	case EBordercolor:		_ctlargcount(g, cp, 2);		_setctlimage(g, &g->bordercolor, cp->args[1]);		break;	case EFocus:		/* ignore focus change */		break;	case EHide:		_ctlargcount(g, cp, 1);		for (i = 0; i < g->nkids; i++)			if (g->kids[i]->ctl)				_ctlprint(g->kids[i], "hide");		g->hidden = 1;		break;	case EImage:		_ctlargcount(g, cp, 2);		_setctlimage(g, &g->image, cp->args[1]);		break;	case ERect:		_ctlargcount(g, cp, 5);		r.min.x = cp->iargs[1];		r.min.y = cp->iargs[2];		r.max.x = cp->iargs[3];		r.max.y = cp->iargs[4];		if(Dx(r)<=0 || Dy(r)<=0)			ctlerror("%q: bad rectangle: %s", g->name, cp->str);		g->rect = r;		r = insetrect(r, g->border);		if (g->nkids == 0)			return;		switch(g->type){		case Ctlboxbox:			boxboxresize(g, r);			break;		case Ctlcolumn:			columnresize(g, r);			break;		case Ctlrow:			rowresize(g, r);			break;		case Ctlstack:			stackresize(g, r);			break;		}		break;	case ERemove:		_ctlargcount(g, cp, 2);		for (n = 0; n < g->nkids; n++)			if (strcmp(cp->args[1], g->kids[n]->name) == 0)				break;		if (n == g->nkids)			ctlerror("%s: remove nonexistent control: %q", g->name, cp->args[1]);		removegroup(g, n);		if (g->setsize)			g->setsize((Control*)g);		break;	case EReveal:		g->hidden = 0;		if (debugr) fprint(2, "reveal %s\n", g->name);		if (g->type == Ctlstack){			if (cp->nargs == 2){				if (cp->iargs[1] < 0 || cp->iargs[1] >= g->nkids)					ctlerror("%s: control out of range: %q", g->name, cp->str);				g->selected = cp->iargs[1];			}else				_ctlargcount(g, cp, 1);			for (i = 0; i < g->nkids; i++)				if (g->kids[i]->ctl){					if (g->selected == i){						if (debugr) fprint(2, "reveal %s: reveal kid %s\n", g->name, g->kids[i]->name);						_ctlprint(g->kids[i], "reveal");					}else{						if (debugr) fprint(2, "reveal %s: hide kid %s\n", g->name, g->kids[i]->name);						_ctlprint(g->kids[i], "hide");					}				}			break;		}		_ctlargcount(g, cp, 1);		if (debug) fprint(2, "reveal %s: border %R/%d\n", g->name, g->rect, g->border);		border(g->screen, g->rect, g->border, g->bordercolor->image, g->bordercolor->image->r.min);		r = insetrect(g->rect, g->border);		if (debug) fprint(2, "reveal %s: draw %R\n", g->name, r);		draw(g->screen, r, g->image->image, nil, g->image->image->r.min);		for (i = 0; i < g->nkids; i++)			if (g->kids[i]->ctl)				_ctlprint(g->kids[i], "reveal");		break;	case EShow:		_ctlargcount(g, cp, 1);		if (g->hidden)			break;		// pass it on to the kiddies		if (debug) fprint(2, "show %s: border %R/%d\n", g->name, g->rect, g->border);		border(g->screen, g->rect, g->border, g->bordercolor->image, g->bordercolor->image->r.min);		r = insetrect(g->rect, g->border);		if (debug) fprint(2, "show %s: draw %R\n", g->name, r);		draw(g->screen, r, g->image->image, nil, g->image->image->r.min);		for (i = 0; i < g->nkids; i++)			if (g->kids[i]->ctl){				if (debug) fprint(2, "show %s: kid %s: %q\n", g->name, g->kids[i]->name, cp->str);				_ctlprint(g->kids[i], "show");			}		flushimage(display, 1);		break;	case ESize:		r.max = Pt(_Ctlmaxsize, _Ctlmaxsize);		if (g->type == Ctlboxbox)			_ctlargcount(g, cp, 5);		switch(cp->nargs){		default:			ctlerror("%s: args of %q", g->name, cp->str);		case 1:			/* recursively set size */			g->mansize = 0;			if (g->setsize)				g->setsize((Control*)g);			break;		case 5:			_ctlargcount(g, cp, 5);			r.max.x = cp->iargs[3];			r.max.y = cp->iargs[4];			/* fall through */		case 3:			r.min.x = cp->iargs[1];			r.min.y = cp->iargs[2];			if(r.min.x<=0 || r.min.y<=0 || r.max.x<=0 || r.max.y<=0 || r.max.x < r.min.x || r.max.y < r.min.y)			ctlerror("%q: bad sizes: %s", g->name, cp->str);			g->size = r;			g->mansize = 1;			break;		}		break;	case ESeparation:		if (g->type != Ctlstack){			_ctlargcount(g, cp, 2);			if(cp->iargs[1] < 0)				ctlerror("%q: illegal value: %c", g->name, cp->str);			g->separation = cp->iargs[1];			break;		}		// fall through for Ctlstack	default:		ctlerror("%q: unrecognized message '%s'", g->name, cp->str);		break;	}}static voidgroupfree(Control *c){	Group *g;	g = (Group*)c;	_putctlimage(g->bordercolor);	free(g->kids);}static voidgroupmouse(Control *c, Mouse *m){	Group *g;	int i, lastkid;	g = (Group*)c;	if (g->type == Ctlstack){		i = g->selected;		if (i >= 0 && g->kids[i]->mouse &&                        ( ( ((m->buttons == 0) || (g->lastbut == 0)) &&                           ptinrect(m->xy, g->kids[i]->rect) ) ||                         ( ((m->buttons != 0) || (g->lastbut != 0)) &&		         (g->lastkid == i) ) ) ) {			if (debugm) fprint(2, "groupmouse %s mouse kid %s i=%d lastkid=%d buttons=%d lastbut=%d inrect=%d\n",						g->name, g->kids[i]->name, i, g->lastkid, m->buttons, g->lastbut,						ptinrect(m->xy, g->kids[i]->rect) ? 1 : 0);			(g->kids[i]->mouse)(g->kids[i], m);			g->lastkid = i;			g->lastbut = m->buttons;		} else {			if (debugm) fprint(2, "groupmouse %s skip kid %s i=%d lastkid=%d buttons=%d lastbut=%d inrect=%d\n",						g->name, g->kids[i]->name, i, g->lastkid, m->buttons, g->lastbut,						ptinrect(m->xy, g->kids[i]->rect) ? 1 : 0);		}		return;	}	lastkid = -1;	for(i=0; i<g->nkids; i++) {		if(g->kids[i]->mouse &&                      ( ( ((m->buttons == 0) || (g->lastbut == 0)) &&                           ptinrect(m->xy, g->kids[i]->rect) ) ||                        ( ((m->buttons != 0) || (g->lastbut != 0)) &&		         (g->lastkid == i) ) ) ) {			if (debugm) fprint(2, "groupmouse %s mouse kid %s i=%d lastkid=%d buttons=%d lastbut=%d inrect=%d\n",						g->name, g->kids[i]->name, i, g->lastkid, m->buttons, g->lastbut,						ptinrect(m->xy, g->kids[i]->rect) ? 1 : 0);			(g->kids[i]->mouse)(g->kids[i], m);			lastkid = i;		} else {			if (debugm) fprint(2, "groupmouse %s skip kid %s i=%d lastkid=%d buttons=%d lastbut=%d inrect=%d\n",						g->name, g->kids[i]->name, i, g->lastkid, m->buttons, g->lastbut,						ptinrect(m->xy, g->kids[i]->rect) ? 1 : 0);		}	}	g->lastkid = lastkid;	g->lastbut = m->buttons;#ifdef notdef	if(m->buttons == 0){		/* buttons now up */		g->lastbut = 0;		return;	}	if(g->lastbut == 0 && m->buttons != 0){		/* button went down, start tracking border */		switch(g->stacking){		default:			return;		case Vertical:			p = Pt(m->xy.x, middle_of_border.y);			p0 = Pt(g->r.min.x, m->xy.y);			p1 = Pt(g->r.max.x, m->xy.y);			break;		case Horizontal:			p = Pt(middle_of_border.x, m->xy.y);			p0 = Pt(m->xy.x, g->r.min.y);			p1 = Pt(m->xy.x, g->r.max.y);			break;		}	//	setcursor();		oi = nil;	} else if (g->lastbut != 0 && s->m.buttons != 0){		/* button is down, keep tracking border */		if(!eqpt(s->m.xy, p)){			p = onscreen(s->m.xy);			r = canonrect(Rpt(p0, p));			if(Dx(r)>5 && Dy(r)>5){				i = allocwindow(wscreen, r, Refnone, 0xEEEEEEFF); /* grey */				freeimage(oi);				if(i == nil)					goto Rescue;				oi = i;				border(i, r, Selborder, red, ZP);				flushimage(display, 1);			}		}	} else if (g->lastbut != 0 && s->m.buttons == 0){		/* button went up, resize kiddies */	}	g->lastbut = s->m.buttons;#endif}static voidactivategroup(Control *c, int act){	int i;	Group *g;	g = (Group*)c;	for (i = 0; i < g->nkids; i++)		if (act)			activate(g->kids[i]);		else			deactivate(g->kids[i]);}Control *createrow(Controlset *cs, char *name){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -