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

📄 fileselect.c

📁 一个很好的SDL建立应用程序界面的例子
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * fileselect.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 <stddef.h>#include <dirent.h>#include <sys/stat.h>#include <unistd.h>#include	<string.h>#include	<ctype.h>#include <errno.h>#include	"widgets.h"#define	MAX_LEN					256#define	DEFAULT_FS_WIDTH		500#define	DIRLIST_X_OFFSET		10#define	DIRLIST_Y_OFFSET		40#define	FILELIST_Y_OFFSET		40typedef struct fileList {	char					*name;	struct fileList	*next;} FILELIST;extern SDL_Surface	*screen;// Prototypesvoid		cancelCB(SDL_Event *event, BUTTON *b);void		okCB(SDL_Event *event, BUTTON *b);void		dirEntryCB(SDL_Event *event, BUTTON *b);void		dirSliderCB(SDL_Event *event, VSLIDER *vs);void		fileEntryCB(SDL_Event *event, BUTTON *b);void		fileSliderCB(SDL_Event *event, VSLIDER *vs);void		adjustFileSlider(int amount);FILELIST	*getDirectories(void);FILELIST	*getFiles(char *pattern[]);void		freeList(FILELIST *list);int		getListCount(FILELIST *list);int		ismatch(char *pattern, char *string);FILELIST	*sortList(FILELIST *list);FILELIST	*mergeList(FILELIST *a, FILELIST *b);// Global varsint		maxWinWidth;int		maxWinHeight;char		*wildcardName[] = {	"*.*",	NULL};char		currentDir[256];char		*selectedFile = NULL;FILELIST	*dirList, *fileList;FILELIST	*list;LABEL		*lab = NULL;BUTTON	*btn = NULL;TEXTBOX	*dirBox = NULL;VSLIDER	*dirSlider = NULL;TEXTBOX	*fileBox = NULL;VSLIDER	*fileSlider = NULL;BUTTON	*cancelBtn = NULL;BUTTON	*okBtn = NULL;int		fileCount, dirCount;int		fileListXOffset;int		ListWidth;int		ListHeight;int		pageCount;bool		closeFS;int		lastActive = 0;int		dirIndex;int		dirOffset;int		fileIndex;int		fileOffset;char		currentFileName[256];char		currentDirName[256];char		**filePattern;FILELIST	*listHead, *listTail;int		listTerminator = -2;WINDOW	*filesel = NULL;////  Select file widget.//  template is a wildcard spec, or NULL for all files.//  path is directory to search, or NULL for current directory.////  Returns a string with the filename selected by the user,//  NULL if no file was selected, or -1 if main screen exited//  while in the file selector.//char *fileSelect(char *pattern[], char *path){	int			x, w;	SDL_Event	event;	closeFS = FALSE;	dirIndex = -1;	fileIndex = -1;	selectedFile = NULL;	fileCount = dirCount = 0;	dirOffset = fileOffset = 0;	if (!pattern)		filePattern = wildcardName;	else		filePattern = pattern;	getcwd(currentDir, 255);	if (!filesel)	{		maxWinWidth = screen->w;		maxWinHeight = screen->h;		if (maxWinWidth > DEFAULT_FS_WIDTH + 20)			w = DEFAULT_FS_WIDTH;		else			w = maxWinWidth - 20;		filesel = newWindow(10, 10, w, maxWinHeight - 20, black, lgray, white, gray);		ListHeight = filesel->h - (DIRLIST_Y_OFFSET + 10) - FONT_HEIGHT;		ListWidth = w / 2 - 40;		fileListXOffset = w / 2 + 6;		pageCount = ListHeight / FONT_HEIGHT - 3;		lab = newLabel(0, 0, black, lgray, white, gray, currentDir);		lab->w = filesel->w;		addLabel(filesel, lab, TRUE);		btn = newButton(DIRLIST_X_OFFSET, DIRLIST_Y_OFFSET - (FONT_HEIGHT + 3), black, lgray, white, gray, " Directories  ");		addButton(filesel, btn, TRUE);		btn = newButton(fileListXOffset, FILELIST_Y_OFFSET - (FONT_HEIGHT + 3), black, lgray, white, gray, " Files        ");		addButton(filesel, btn, TRUE);		dirBox = newTextBox(DIRLIST_X_OFFSET, DIRLIST_Y_OFFSET, ListWidth, ListHeight, black, white, lgray, gray);		attachCallBack(dirBox, SDL_MOUSEBUTTONDOWN, (void *) &dirEntryCB);		fileBox = newTextBox(fileListXOffset, FILELIST_Y_OFFSET, ListWidth, ListHeight, black, white, lgray, gray);		attachCallBack(fileBox, SDL_MOUSEBUTTONDOWN, (void *) &fileEntryCB);		addTextBox(filesel, dirBox);		addTextBox(filesel, fileBox);		dirSlider = newVSlider(DIRLIST_X_OFFSET + ListWidth + 5, DIRLIST_Y_OFFSET + 1, 15, ListHeight - 2, lgray, lgray, white, gray, 0, 0);		attachCallBack(dirSlider, SDL_MOUSEBUTTONDOWN, (void *) &dirSliderCB);		attachCallBack(dirSlider, SDL_MOUSEMOTION, (void *) &dirSliderCB);		attachCallBack(dirSlider, SLIDER_AUTO_CALLBACK, (void *) &dirSliderCB);		addVSlider(filesel, dirSlider);		fileSlider = newVSlider(fileListXOffset + ListWidth + 5, FILELIST_Y_OFFSET + 1, 15, ListHeight - 2, lgray, lgray, white, gray, 0, 0);		attachCallBack(fileSlider, SDL_MOUSEBUTTONDOWN, (void *) &fileSliderCB);		attachCallBack(fileSlider, SDL_MOUSEMOTION, (void *) &fileSliderCB);		attachCallBack(fileSlider, SLIDER_AUTO_CALLBACK, (void *) &fileSliderCB);		addVSlider(filesel, fileSlider);		x = DIRLIST_X_OFFSET + ListWidth / 2 - 5 * FONT_WIDTH;		cancelBtn = newButton(x, maxWinHeight - (FONT_HEIGHT * 3), black, lgray, white, black, " Cancel ");		attachCallBack(cancelBtn, SDL_MOUSEBUTTONDOWN, (void *) &cancelCB);		x = fileListXOffset + ListWidth / 2 - 4 * FONT_WIDTH;		okBtn = newButton(x, maxWinHeight - (FONT_HEIGHT * 3), black, lgray, white, black, "  Ok  ");		attachCallBack(okBtn, SDL_MOUSEBUTTONDOWN, (void *) &okCB);		addButton(filesel, cancelBtn, TRUE);		addButton(filesel, okBtn, TRUE);		listHead = (FILELIST *) malloc(sizeof(FILELIST));		listHead->name = NULL;		listHead->next = NULL;		listTail = (FILELIST *) malloc(sizeof(FILELIST));		listTail->name = (char *) &listTerminator;		listTail->next = listTail;	}	fileSlider->position = 0;	dirSlider->position = 0;	dirList = getDirectories();	if (dirList)	{		dirCount = getListCount(dirList);		dirSlider->range = dirCount;		if (dirCount < 20)			dirSlider->change = 1;		else			dirSlider->change = 20;		if (dirCount)		{			dirList = sortList(dirList);			list = dirList;			while (list)			{				addText(dirBox, list->name);				list = list->next;			}		}	}	fileList = getFiles(filePattern);	if (fileList)	{		fileCount = getListCount(fileList);		fileSlider->range = fileCount;		if (fileCount < 20)			fileSlider->change = 1;		else			fileSlider->change = 20;		if (fileCount)		{			fileList = sortList(fileList);			list = fileList;			while (list)			{				addText(fileBox, list->name);				list = list->next;			}		}	}	popUpWidget(filesel);	updateScreen();	while (!closeFS)	{		SDL_UpdateRect(screen, 0, 0, 0, 0);		if (!SDL_PollEvent(NULL))			SDL_WaitEvent(NULL);		while (SDL_PollEvent(&event))		{			switch (event.type)			{				case SDL_MOUSEBUTTONDOWN:					processCB(&event);					break;				case SDL_MOUSEBUTTONUP:					processCB(&event);					dirSlider->drag = FALSE;					dirSlider->state = MOUSE_NOT_IN_SLIDER;					fileSlider->drag = FALSE;					fileSlider->state = MOUSE_NOT_IN_SLIDER;					if (!closeFS)					{						popUpWidget(filesel);						updateScreen();					}					break;				case SDL_MOUSEMOTION:					processCB(&event);					SDL_UpdateRect(screen, 0, 0, 0, 0);					while (SDL_PollEvent(&event))					{						if (event.type != SDL_MOUSEMOTION)						{							if (event.type == SDL_MOUSEBUTTONUP)							{								dirSlider->drag = FALSE;								dirSlider->state = MOUSE_NOT_IN_SLIDER;								fileSlider->drag = FALSE;								fileSlider->state = MOUSE_NOT_IN_SLIDER;								if (!closeFS)								{									popUpWidget(filesel);									updateScreen();								}							}							SDL_PushEvent(&event);							break;						}					}					break;				case SDL_KEYDOWN:					switch (event.key.keysym.sym)					{						case SDLK_UP:							adjustFileSlider(-1);							break;						case SDLK_DOWN:							adjustFileSlider(1);							break;						case SDLK_PAGEUP:							adjustFileSlider(-pageCount);							break;						case SDLK_PAGEDOWN:							adjustFileSlider(pageCount);							break;						default:							break;					}					break;				case TIMER_EVENT:					if (!closeFS && (topWidget == dirSlider || topWidget == fileSlider))						processCB(&event);					break;				case SDL_QUIT:					closeFS = TRUE;					selectedFile = (char *) -1;					pushDownWidget(filesel);					break;			}		}	}	if (fileList)		freeList(fileList);	if (dirList)		freeList(dirList);	removeTList(dirBox);	removeTList(fileBox);	pushDownWidget(filesel);	return selectedFile;}void adjustFileSlider(int amount){	int		pos, pc, loc;	int		*offset, *count;	VSLIDER	*vs;	TEXTBOX	*box;	if (((WIDGET *) topWidget)->p.type == AlertType)		return;	if (!lastActive)	{		vs = fileSlider;		box = fileBox;		offset = (int *) &fileOffset;		count = (int *) &fileCount;	}	else	{		vs = dirSlider;		box = dirBox;		offset = (int *) &dirOffset;		count = (int *) &dirCount;	}	loc = *offset + amount;	if (loc < 0)		loc = 0;	else if (loc >= *count)		loc = *count - 1;	*offset = loc;	pc = (loc * 100) / *count;	pos = (pc * vs->h) / 100;	vs->position = pos;	setTListEntry(box, loc);	showWidget(box);	showWidget(vs);}void cancelCB(SDL_Event *event, BUTTON *b){	if (((WIDGET *) topWidget)->p.type == AlertType)		return;	closeFS = TRUE;	pushDownWidget(filesel);	selectedFile = NULL;}void okCB(SDL_Event *event, BUTTON *b){	if (((WIDGET *) topWidget)->p.type == AlertType)		return;	closeFS = TRUE;	pushDownWidget(filesel);	if (fileIndex >= 0)	{		strcpy(currentFileName, currentDir);		strcat(currentFileName, "/");		strcat(currentFileName, getText(fileBox, fileIndex + 1));		selectedFile = (char *) &currentFileName;	}	else		selectedFile = NULL;}void dirSliderCB(SDL_Event *event, VSLIDER *vs){	int	loc;	if (((WIDGET *) topWidget)->p.type == AlertType)		return;	lastActive = 1;	loc = dirSlider->offset;	if (loc < 0)		loc = 0;	else if (loc >= dirCount)		loc = dirCount - 1;	setTListEntry(dirBox, loc);	dirOffset = loc;}void fileSliderCB(SDL_Event *event, VSLIDER *vs){	int	loc;	if (((WIDGET *) topWidget)->p.type == AlertType)		return;	lastActive = 0;	loc = fileSlider->offset;	if (loc < 0)		loc = 0;	else if (loc >= fileCount)		loc = fileCount - 1;	setTListEntry(fileBox, loc);	fileOffset = loc;}void dirEntryCB(SDL_Event *event, BUTTON *b){	int	x, y, xlim, ylim, mx, my, index;	if (((WIDGET *) topWidget)->p.type == AlertType)		return;

⌨️ 快捷键说明

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