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

📄 widgets.c

📁 一个很好的SDL建立应用程序界面的例子
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * widgets.c - SDL widget set in C * * Copyright 2004 by Jeffery L. Post * theposts<AT>pacbell<DOT>net * Version 0.0.3 - 11/26/04 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include	<stdio.h>#include	<stdlib.h>#include	<string.h>#include	<ctype.h>#include	<signal.h>#include	<sys/time.h>#include	"widgets.h"#define	CURSOR_Y_OFFSET	1	// this insures that the cursor is under the character// We use a system interval timer because SDL timers screw up popen(), exec(), etc.#define	WIDGET_TIMER_UPDATE_TIME		50#define	WIDGET_SLIDER_REPEAT_DELAY		3#define	IBOX_CURSOR_DELAY					5struct timer_data {	int		*timeout;	VSLIDER	*vs;};extern SDL_Surface	*screen;// Local prototypesvoid	widgetTimerCB(void);void	blankScreen(void);int	printString(int x, int y, int fg, int bg, char *str);int	printHLString(int x, int y, int fg, int bg, char *str);void	drawCursor(int x, int y, int fg, char chr);void	setPixel(int x, int y, int color);void	shiftStringUp(char *str, int index);void	shiftStringDown(char *str, int index);int	whereInSlider(void *slider, int mx, int my);bool	tweakSlider(VSLIDER *sp, int x, int y, int where);void	adjustSlider(void *slider, int amount);void	updateSlider(SDL_Event *ev, void *slider);void	makeBar(int x, int y, int w, int h, int color);void	processAlertCallBack(SDL_Event *ev, BUTTON * btn);void	processNoticeCallBack(SDL_Event *ev, BUTTON * btn);bool	childInParent(void *parent, void *child);int	maxWidth(WINDOW *win);void	updateIBox(SDL_Event *event, INPUTBOX *b);void	showWindow(WINDOW *w);void	showVMenu(VMENU *w);void	showAlertBox(WINDOW *w);void	showNoticeBox(WINDOW *w);void	showTextBox(TEXTBOX *w);void	showInputBox(INPUTBOX *w);void	showButton(BUTTON *b);void	showLabel(LABEL *lab);void	showHLabel(HLABEL *lab);void	showCheckBox(CHECKBOX *cb);void	showLeftArrow(int x, int y);void	showRightArrow(int x, int y);void	showUpArrow(int x, int y);void	showDownArrow(int x, int y);void	showVSlider(VSLIDER *vs);void	showHSlider(HSLIDER *hs);void	addWList(void *w);void	removeWList(void *w);// Global variables#ifdef DEBUG// widget_names MUST match enum WidgetType in widgets.hchar	*widget_names[] = {	"Window",	"Menu",	"VMenu",	"Button",	"CheckBox",	"Label",	"HLabel",	"Alert",	"Notice",	"TextBox",	"InputBox",	"VSlider",	"HSlider",	"Invalid Widget",};#endif	// DEBUGint		widgetRepeatDelay = WIDGET_SLIDER_REPEAT_DELAY;#ifndef WIN32struct itimerval	vtimer;#endifstruct timer_data timerData = {	&widgetRepeatDelay,	NULL,};// Simulated mouse button down event for automatic callbacksSDL_MouseButtonEvent timerEvent = {	SDL_MOUSEBUTTONDOWN,		// simulate mouse button down event	0,								// mouse device index	0,								// mouse button index	SDL_PRESSED,				// state	0,								// x coordinate	0,								// y coordinate};// Timer event for auto callbackSDL_Event	AlarmEvent = {TIMER_EVENT};int		widget_id = 0;void		*topWidget = NULL;int		screen_width;int		screen_height;Uint8		bits_per_pixel;Uint8		bytes_per_pixel;Uint16	pitch;// ColorsUint32	black;		// 0Uint32	blue;			// 1Uint32	green;		// 2Uint32	cyan;			// 3Uint32	red;			// 4Uint32	magenta;		// 5Uint32	brown;		// 6Uint32	lgray;		// 7Uint32	gray;			// 8Uint32	lblue;		// 9Uint32	lgreen;		// 10Uint32	lcyan;		// 11Uint32	lred;			// 12Uint32	lmagenta;	// 13Uint32	yellow;		// 14Uint32	white;		// 15Uint32	lyellow;		// 16Uint32	dyellow;		// 17Uint32	pink;			// 18Uint32	dblue;		// 19Uint32	dgreen;		// 20WLIST		*wlist = NULL;#ifdef DEBUGvoid dump_widget_list(void){	int		i;	WLIST 	*next;	WIDGET	*w;		printf("\nWidget List at 0x%x:\n", (int) wlist);	next = wlist;	i = 1;	while (next)	{		w = next->w;		printf("%2d: widget %d at 0x%x, entry 0x%x, %s, parent 0x%x, x %d, y %d, w %d, h %d.",			i, w->p.id, (int) w, (int) next, widget_names[w->p.type], (int) w->p.parent, w->p.x, w->p.y, w->p.w, w->p.h);		printf(" Callbacks: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",			(int) w->p.mdfunc, (int) w->p.mufunc, (int) w->p.mmfunc, (int) w->p.kdfunc, (int) w->p.kufunc);		fflush(stdout);		next = next->next;		i++;	}	if (topWidget)		printf("topWidget 0x%x, %s\n", (int) topWidget, widget_names[((WIDGET *) topWidget)->p.type]);}#endif/* * Functions * */void SigHandler(int sig){#ifndef WIN32	if (sig == SIGALRM)		SDL_PushEvent(&AlarmEvent);#else	SDL_PushEvent(&AlarmEvent);#endif}// Display a character with given colors at given coordinatesvoid drawChar(int x, int y, int fg, int bg, char chr){	int	i, j, b;	int	bpp, neg;	Uint8	*row;	b = (int) (Uint8) chr * FONT_WIDTH * FONT_HEIGHT;	bpp = (int) bytes_per_pixel;	neg = FONT_WIDTH * bpp;	row = (Uint8 *) screen->pixels + y * pitch + x * bpp;	switch (bytes_per_pixel)	{		case 1:			for (i=0; i<FONT_HEIGHT; i++, y++)			{				row += pitch;				for (j=0; j<FONT_WIDTH; j++)				{					if (fontdata[b + j])						*row = (Uint8) fg;					else						*row = (Uint8) bg;					row += bpp;				}				b += FONT_WIDTH;				row -= neg;			}			break;		case 2:			for (i=0; i<FONT_HEIGHT; i++, y++)			{				row += pitch;				for (j=0; j<FONT_WIDTH; j++)				{					if (fontdata[b + j])						*(Uint16 *)row = (Uint16) fg;					else						*(Uint16 *)row = (Uint16) bg;					row += bpp;				}				b += FONT_WIDTH;				row -= neg;			}			break;		case 4:			for (i=0; i<FONT_HEIGHT; i++, y++)			{				row += pitch;				for (j=0; j<FONT_WIDTH; j++)				{					if (fontdata[b + j])						*(Uint32 *)row = (Uint32) fg;					else						*(Uint32 *)row = (Uint32) bg;					row += bpp;				}				b += FONT_WIDTH;				row -= neg;			}			break;	}}// Display cursorvoid drawCursor(int x, int y, int fg, char chr){	int	i, j, b;	int	bpp, neg;	Uint8	*row;	b = (int) (Uint8) chr * FONT_WIDTH * FONT_HEIGHT;	bpp = (int) bytes_per_pixel;	neg = FONT_WIDTH * bpp;	y += CURSOR_Y_OFFSET;	row = (Uint8 *) screen->pixels + y * pitch + x * bpp;	switch (bytes_per_pixel)	{		case 1:			for (i=0; i<FONT_HEIGHT; i++, y++)			{				row += pitch;				for (j=0; j<FONT_WIDTH; j++)				{					if (fontdata[b + j])						*row = (Uint8) fg;					row += bpp;				}				b += FONT_WIDTH;				row -= neg;			}			break;		case 2:			for (i=0; i<FONT_HEIGHT; i++, y++)			{				row += pitch;				for (j=0; j<FONT_WIDTH; j++)				{					if (fontdata[b + j])						*(Uint16 *)row = (Uint16) fg;					row += bpp;				}				b += FONT_WIDTH;				row -= neg;			}			break;		case 4:			for (i=0; i<FONT_HEIGHT; i++, y++)			{				row += pitch;				for (j=0; j<FONT_WIDTH; j++)				{					if (fontdata[b + j])						*(Uint32 *)row = (Uint32) fg;					row += bpp;				}				b += FONT_WIDTH;				row -= neg;			}			break;	}}// Set pixel at given coordinates to the given colorvoid setPixel(int x, int y, int color){	Uint8		*row8;	Uint16	*row16;	Uint32	*row32;	switch (bytes_per_pixel)	{		case 1:			row8 = (Uint8 *) ((int) screen->pixels + y * pitch + x * bytes_per_pixel);			*row8 = (Uint8) color;			break;		case 2:			row16 = (Uint16 *) ((int) screen->pixels + y * pitch + x * bytes_per_pixel);			*row16 = (Uint16) color;			break;		case 4:			row32 = (Uint32 *) ((int) screen->pixels + y * pitch + x * bytes_per_pixel);			*row32 = (Uint32) color;			break;	}}// Display a stringint printString(int x, int y, int fg, int bg, char *str){	int	i;	char	chr;	i = 0;	while (*str)	{		chr = *str++;		drawChar(x, y, fg, bg, chr);		x += FONT_WIDTH;		i++;	}	return i;}// Display a highlighted stringint printHLString(int x, int y, int fg, int bg, char *str){	int	i;	char	chr;	i = 0;	while (*str)	{		chr = *str++;		if (chr & 0x80)			drawChar(x, y, bg, fg, chr & 0x7f);		else			drawChar(x, y, fg, bg, chr);		x += FONT_WIDTH;		i++;	}	return i;}void shiftStringUp(char *str, int index){	int	len;	len = strlen(str);	while (len > index)	{		str[len] = str[len - 1];		--len;	}}void shiftStringDown(char *str, int index){	do	{		str[index] = str[index + 1];		index++;	} while (str[index]);}// Initialize the video systemvoid initWidgets(void){	SDL_VideoInfo		*v_info;	SDL_PixelFormat	*vfmt;	v_info = (SDL_VideoInfo *) SDL_GetVideoInfo();	if (!v_info)	{		printf("\n\nCan't get video info: %s\n\n", SDL_GetError());		exit(1);	}	screen_width = screen->w;	screen_height = screen->h;	vfmt = screen->format;	bits_per_pixel = vfmt->BitsPerPixel;	bytes_per_pixel = vfmt->BytesPerPixel;	pitch = screen->pitch;	SDL_EnableUNICODE(TRUE);#ifndef WIN32	signal(SIGALRM, SigHandler);				// set up a signal handler	vtimer.it_interval.tv_sec = 0;			// set a 50msec interval timer	vtimer.it_interval.tv_usec = (WIDGET_TIMER_UPDATE_TIME * 1000);	vtimer.it_value.tv_sec = 0;	vtimer.it_value.tv_usec = (WIDGET_TIMER_UPDATE_TIME * 1000);	setitimer(ITIMER_REAL, &vtimer, NULL);#else	SetTimer(NULL, 0, WIDGET_TIMER_UPDATE_TIME, (VOID CALLBACK*) &SigHandler);#endif//                                       R             G             B	black		= SDL_MapRGB(vfmt, (Uint8) 0x00, (Uint8) 0x00, (Uint8) 0x00);	// 0	blue     = SDL_MapRGB(vfmt, (Uint8) 0x00, (Uint8) 0x00, (Uint8) 0xd0);	// 1	green    = SDL_MapRGB(vfmt, (Uint8) 0x00, (Uint8) 0xd0, (Uint8) 0x00);	// 2	cyan     = SDL_MapRGB(vfmt, (Uint8) 0x00, (Uint8) 0xa6, (Uint8) 0xa6);	// 3	red      = SDL_MapRGB(vfmt, (Uint8) 0xa6, (Uint8) 0x00, (Uint8) 0x00);	// 4	magenta  = SDL_MapRGB(vfmt, (Uint8) 0xa6, (Uint8) 0x00, (Uint8) 0xa6);	// 5	brown    = SDL_MapRGB(vfmt, (Uint8) 0xa6, (Uint8) 0x54, (Uint8) 0x00);	// 6	lgray    = SDL_MapRGB(vfmt, (Uint8) 0xd0, (Uint8) 0xd0, (Uint8) 0xd0);	// 7	gray     = SDL_MapRGB(vfmt, (Uint8) 0xa6, (Uint8) 0xa6, (Uint8) 0xa6);	// 8	lblue    = SDL_MapRGB(vfmt, (Uint8) 0x00, (Uint8) 0x00, (Uint8) 0xff);	// 9	lgreen   = SDL_MapRGB(vfmt, (Uint8) 0x00, (Uint8) 0xff, (Uint8) 0x00);	// 10	lcyan    = SDL_MapRGB(vfmt, (Uint8) 0x54, (Uint8) 0xff, (Uint8) 0xff);	// 11	lred     = SDL_MapRGB(vfmt, (Uint8) 0xff, (Uint8) 0x00, (Uint8) 0x00);	// 12	lmagenta = SDL_MapRGB(vfmt, (Uint8) 0xff, (Uint8) 0x54, (Uint8) 0xff);	// 13	yellow   = SDL_MapRGB(vfmt, (Uint8) 0xff, (Uint8) 0xff, (Uint8) 0x54);	// 14	white		= SDL_MapRGB(vfmt, (Uint8) 0xff, (Uint8) 0xff, (Uint8) 0xff);	// 15	lyellow	= SDL_MapRGB(vfmt, (Uint8) 0xff, (Uint8) 0xff, (Uint8) 0xc0);	// 16	dyellow	= SDL_MapRGB(vfmt, (Uint8) 0xa6, (Uint8) 0xa6, (Uint8) 0x00);	// 17	pink		= SDL_MapRGB(vfmt, (Uint8) 0xff, (Uint8) 0xa6, (Uint8) 0xa6);	// 18	dblue		= SDL_MapRGB(vfmt, (Uint8) 0x00, (Uint8) 0x00, (Uint8) /*0xa6*/0x80);	// 19	dgreen	= SDL_MapRGB(vfmt, (Uint8) 0x00, (Uint8) 0x80, (Uint8) 0x00);	// 20}void widgetQuit(void){	timerData.vs = NULL;}// Blank the entire screen to blackvoid blankScreen(void){	SDL_Rect	blank_area;	blank_area.x = 0;	blank_area.y = 0;	blank_area.w = screen_width;	blank_area.h = screen_height;	SDL_FillRect(screen, (SDL_Rect *) &blank_area, 0);}// Mouse button down event has occurred on an AlertBox Cancel or OK button.// Set the response code for the parent widget (the AlertBox), and then// call its mousebuttondown function.void processAlertCallBack(SDL_Event *ev, BUTTON * btn){	ALERT	*parent;	char		*c;	void		(*fptr)(SDL_Event *, void *);	parent = btn->parent;	c = btn->text;	if (!strcmp(c, " Cancel "))		parent->response = ALERT_CANCEL;	else if (!strcmp(c, " OK "))		parent->response = ALERT_OK;	else		parent->response = ALERT_NO_RESPONSE;	fptr = parent->mdfunc;	if (fptr)		(*fptr)(ev, parent);	updateScreen();}// Mouse button down event has occurred on an NoticeBox Close button.void processNoticeCallBack(SDL_Event *ev, BUTTON * btn){	NOTICE	*parent;	void		(*fptr)(SDL_Event *, void *);	parent = btn->parent;	fptr = parent->mdfunc;	if (fptr)		(*fptr)(ev, parent);	pushDownWidget(parent);	updateScreen();}void attachCallBack(void *w, int type, void *func){	WIDGET	*x;	x = (WIDGET *) w;	switch (type)	{		case SDL_MOUSEBUTTONDOWN:			x->p.mdfunc = func;			break;		case SDL_MOUSEBUTTONUP:			x->p.mufunc = func;			break;		case SDL_MOUSEMOTION:			x->p.mmfunc = func;			break;		case SDL_KEYDOWN:			x->p.kdfunc = func;			break;		case SDL_KEYUP:			x->p.kufunc = func;			break;		case SLIDER_AUTO_CALLBACK:			if (x->p.type == VSliderType || x->p.type == HSliderType)				((VSLIDER *) x)->adjfunc = func;			break;	}}void removeCallBack(void *w, int type){	WIDGET	*x;	x = (WIDGET *) w;	switch (type)	{		case SDL_MOUSEBUTTONDOWN:			x->p.mdfunc = NULL;			break;		case SDL_MOUSEBUTTONUP:			x->p.mufunc = NULL;			break;		case SDL_MOUSEMOTION:			x->p.mmfunc = NULL;			break;		case SDL_KEYDOWN:			x->p.kdfunc = NULL;			break;		case SDL_KEYUP:			x->p.kufunc = NULL;			break;		case SLIDER_AUTO_CALLBACK:			if (x->p.type == VSliderType || x->p.type == HSliderType)				((VSLIDER *) x)->adjfunc = NULL;			break;	}}// A dummy callback function which does nothing at all.// This is available so that users can attach it to a// Label or other widget when they don't really want to// do anything except prevent underlying widgets from// executing their callbacks.void nullCallBack(void *w, ...){	// do nothing}// Return TRUE if child widget displays inside parent widgetbool childInParent(void *parent, void *child){	int		x, y;	WIDGET	*p, *c;	p = (WIDGET *) parent;	c = (WIDGET *) child;	x = c->p.x;	y = c->p.y;	if (x >= p->p.x && x <= p->p.x + p->p.w && y >= p->p.y && y <= p->p.y + p->p.h)		return TRUE;	return FALSE;}// Allocate a window structureWINDOW *newWindow(int x, int y, int w, int h, int fg, int bg, int hi, int lo){	WINDOW *win = (WINDOW *) malloc(sizeof(WINDOW));	win->type = WindowType;	win->id = widget_id++;	win->x = x;	win->y = y;	win->w = w;	win->h = h;	win->fg = fg;	win->bg = bg;	win->hi = hi;	win->lo = lo;	win->mdfunc = NULL;	win->mufunc = NULL;	win->mmfunc = NULL;	win->kdfunc = NULL;	win->kufunc = NULL;	win->parent = NULL;	win->list = NULL;	return win;}// Allocate a menu structureMENU *newMenu(int x, int y, int w, int h, int fg, int bg, int hi, int lo){	MENU *menu = (MENU *) malloc(sizeof(MENU));	menu->type = MenuType;	menu->id = widget_id++;

⌨️ 快捷键说明

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