slider.c

来自「这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易」· C语言 代码 · 共 327 行

C
327
字号
#include <u.h>#include <libc.h>#include <draw.h>#include <thread.h>#include <mouse.h>#include <keyboard.h>#include <control.h>typedef struct Slider Slider;struct Slider{	Control;	int		border;	CImage	*image;	CImage	*textcolor;	CImage	*bordercolor;	CImage	*indicatorcolor;	int		absolute;	int		max;	int		vis;	int		value;	int		clamphigh;	int		clamplow;	int		horizontal;	int		lastbut;};enum{	EAbsolute,	EBorder,	EBordercolor,	EClamp,	EFocus,	EFormat,	EHide,	EImage,	EIndicatorcolor,	EMax,	EOrient,	ERect,	EReveal,	EShow,	ESize,	EValue,	EVis,};static char *cmds[] = {	[EAbsolute] =		"absolute",	[EBorder] =		"border",	[EBordercolor] =	"bordercolor",	[EClamp] =		"clamp",	[EFocus] = 		"focus",	[EFormat] = 		"format",	[EHide] =			"hide",	[EImage] =		"image",	[EIndicatorcolor] =	"indicatorcolor",	[EMax] =			"max",	[EOrient] =		"orient",	[ERect] =			"rect",	[EReveal] =		"reveal",	[EShow] =			"show",	[ESize] =			"size",	[EValue] =			"value",	[EVis] =			"vis",};static voidsliderfree(Control *c){	Slider *s;	s = (Slider*)c;	_putctlimage(s->image);	_putctlimage(s->textcolor);	_putctlimage(s->bordercolor);	_putctlimage(s->indicatorcolor);}static voidslidershow(Slider *s){	Rectangle r, t;	int l, h, d;	if (s->hidden)		return;	r = s->rect;	draw(s->screen, r, s->image->image, nil, s->image->image->r.min);	if(s->border > 0){		border(s->screen, r, s->border, s->bordercolor->image, s->bordercolor->image->r.min);		r = insetrect(r, s->border);	}	if(s->max <= 0)		return;	if(s->horizontal)		d = Dx(r);	else		d = Dy(r);	l = muldiv(s->value, d, s->max);	h = muldiv(s->value+s->vis, d, s->max);	if(s->clamplow && s->clamphigh){		l = 0;		h = d;	}else if(s->clamplow){		h = l;		l = 0;	}else if(s->clamphigh)		h = d;	t = r;	if(s->horizontal){		r.max.x = r.min.x+h;		r.min.x += l;	}else{		r.max.y = r.min.y+h;		r.min.y += l;	}	if(rectclip(&r, t))		draw(s->screen, r, s->indicatorcolor->image, nil, s->indicatorcolor->image->r.min);	flushimage(display, 1);}static voidsliderctl(Control *c, CParse *cp){	int cmd, prev;	Rectangle r;	Slider *s;	s = (Slider*)c;	cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));	switch(cmd){	default:		ctlerror("%q: unrecognized message '%s'", s->name, cp->str);		break;	case EAbsolute:		_ctlargcount(s, cp, 2);		s->absolute = cp->iargs[1];		break;	case EBorder:		_ctlargcount(s, cp, 2);		if(cp->iargs[1] < 0)			ctlerror("%q: bad border: %c", s->name, cp->str);		s->border = cp->iargs[1];		break;	case EBordercolor:		_ctlargcount(s, cp, 2);		_setctlimage(s, &s->bordercolor, cp->args[1]);		break;	case EClamp:		_ctlargcount(s, cp, 3);		if(strcmp(cp->args[1], "high") == 0)			s->clamphigh = cp->iargs[2];		else if(strcmp(cp->args[1], "low") == 0)			s->clamplow = cp->iargs[2];		else			ctlerror("%q: unrecognized clamp: %s", s->name, cp->str);		break;	case EFocus:		/* ignore focus change */		break;	case EFormat:		_ctlargcount(s, cp, 2);		s->format = ctlstrdup(cp->args[1]);		break;	case EHide:		_ctlargcount(s, cp, 1);		s->hidden = 1;		break;	case EImage:		_ctlargcount(s, cp, 2);		_setctlimage(s, &s->image, cp->args[1]);		break;	case EIndicatorcolor:		_ctlargcount(s, cp, 2);		_setctlimage(s, &s->indicatorcolor, cp->args[1]);		break;	case EMax:		_ctlargcount(s, cp, 2);		if(cp->iargs[1] < 0)			ctlerror("%q: negative max value: %s", s->name, cp->str);		if(s->max != cp->iargs[1]){			s->max = cp->iargs[1];			slidershow(s);		}		break;	case EOrient:		_ctlargcount(s, cp, 2);		prev = s->horizontal;		if(strncmp(cp->args[1], "hor", 3) == 0)			s->horizontal = 1;		else if(strncmp(cp->args[1], "ver", 3) == 0)			s->horizontal = 0;		else			ctlerror("%q: unrecognized orientation: %s", s->name, cp->str);		if(s->horizontal != prev)			slidershow(s);		break;	case ERect:		_ctlargcount(s, 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", s->name, cp->str);		s->rect = r;		break;	case EReveal:		_ctlargcount(s, cp, 1);		s->hidden = 0;		slidershow(s);		break;	case EShow:		_ctlargcount(s, cp, 1);		slidershow(s);		break;	case ESize:		if (cp->nargs == 3)			r.max = Pt(0x7fffffff, 0x7fffffff);		else{			_ctlargcount(s, cp, 5);			r.max.x = cp->iargs[3];			r.max.y = cp->iargs[4];		}		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", s->name, cp->str);		s->size.min = r.min;		s->size.max = r.max;		break;	case EValue:		_ctlargcount(s, cp, 2);		if(s->value != cp->iargs[1]){			s->value = cp->iargs[1];			slidershow(s);		}		break;	case EVis:		_ctlargcount(s, cp, 2);		if(s->vis != cp->iargs[1]){			s->vis = cp->iargs[1];			slidershow(s);		}		break;	}}static voidslidermouse(Control *c, Mouse *m){	Rectangle r;	int v, l, d, b;	Slider *s;	s =(Slider*)c;	if(m->buttons == 0){		/* buttons now up */		s->lastbut = 0;		return;	}	if(!s->absolute && s->lastbut==m->buttons && s->lastbut!=2){		/* clicks only on buttons 1 & 3; continuous motion on 2 (or when absolute) */		return;	}	if(s->lastbut!=0 && m->buttons!=s->lastbut){		/* buttons down have changed; wait for button up */		return;	}	s->lastbut = m->buttons;	r = insetrect(s->rect, s->border);	if(s->horizontal){		v = m->xy.x - r.min.x;		d = Dx(r);	}else{		v = m->xy.y - r.min.y;		d = Dy(r);	}	if(s->absolute)		b = 2;	else		b = m->buttons;	switch(b){	default:		return;	case 1:		l = s->value - muldiv(v, s->vis, d);		break;	case 2:		l = muldiv(v, s->max, d);		break;	case 4:		l = s->value + muldiv(v, s->vis, d);		break;	}	if(l < 0)		l = 0;	if(l > s->max)		l = s->max;	if(l != s->value){		s->value = l;		chanprint(s->event, s->format, s->name, s->value);		slidershow(s);	}}Control*createslider(Controlset *cs, char *name){	Slider *s;	s = (Slider*)_createctl(cs, "slider", sizeof(Slider), name);	s->image = _getctlimage("white");	s->textcolor = _getctlimage("black");	s->bordercolor = _getctlimage("black");	s->indicatorcolor = _getctlimage("black");	s->format = ctlstrdup("%q: value %d");	s->border = 0;	s->mouse = slidermouse;	s->ctl = sliderctl;	s->exit = sliderfree;	return (Control*)s;}

⌨️ 快捷键说明

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