示例#1
0
boolean dialogChooseFile(char *path, const char *suffix, const char *prompt) {
	short i, j, count, x, y, width, height, suffixLength, pathLength, maxPathLength, currentPageStart;
	brogueButton buttons[FILES_ON_PAGE_MAX + 2];
	fileEntry *files;
	boolean retval = false, again;
	cellDisplayBuffer dbuf[COLS][ROWS], rbuf[COLS][ROWS];
	color *dialogColor = &interfaceBoxColor;
	char *membuf;
	
	suffixLength = strlen(suffix);
	files = listFiles(&count, &membuf);
	copyDisplayBuffer(rbuf, displayBuffer);
	maxPathLength = strLenWithoutEscapes(prompt);
	
	// First, we want to filter the list by stripping out any filenames that do not end with suffix.
	// i is the entry we're testing, and j is the entry that we move it to if it qualifies.
	for (i=0, j=0; i<count; i++) {
		pathLength = strlen(files[i].path);
		//printf("\nString 1: %s", &(files[i].path[(max(0, pathLength - suffixLength))]));
		if (stringsExactlyMatch(&(files[i].path[(max(0, pathLength - suffixLength))]), suffix)) {
			
			// This file counts!
			if (i > j) {
				files[j] = files[i];
				//printf("\nMatching file: %s\twith date: %s", files[j].path, files[j].date);
			}
			j++;
			
			// Keep track of the longest length.
			if (min(pathLength, MAX_FILENAME_DISPLAY_LENGTH) + 10 > maxPathLength) {
				maxPathLength = min(pathLength, MAX_FILENAME_DISPLAY_LENGTH) + 10;
			}
		}
	}
	count = j;
	
	currentPageStart = 0;
	
	do { // Repeat to permit scrolling.
		again = false;
		
		for (i=0; i<min(count - currentPageStart, FILES_ON_PAGE_MAX); i++) {
			initializeButton(&(buttons[i]));
			buttons[i].flags &= ~(B_WIDE_CLICK_AREA | B_GRADIENT);
			buttons[i].buttonColor = *dialogColor;
            if (KEYBOARD_LABELS) {
                sprintf(buttons[i].text, "%c) ", 'a' + i);
            } else {
                buttons[i].text[0] = '\0';
            }
			strncat(buttons[i].text, files[currentPageStart+i].path, MAX_FILENAME_DISPLAY_LENGTH);
			
			// Clip off the file suffix from the button text.
			buttons[i].text[strlen(buttons[i].text) - suffixLength] = '\0'; // Snip!
			buttons[i].hotkey[0] = 'a' + i;
			buttons[i].hotkey[1] = 'A' + i;
			
			// Clip the filename length if necessary.
			if (strlen(buttons[i].text) > MAX_FILENAME_DISPLAY_LENGTH) {
				strcpy(&(buttons[i].text[MAX_FILENAME_DISPLAY_LENGTH - 3]), "...");
			}
			
			//printf("\nFound file: %s, with date: %s", files[currentPageStart+i].path, files[currentPageStart+i].date);
		}
		
		x = (COLS - maxPathLength) / 2;
		width = maxPathLength;
		height = min(count - currentPageStart, FILES_ON_PAGE_MAX) + 2;
		y = max(4, (ROWS - height) / 2);
		
		for (i=0; i<min(count - currentPageStart, FILES_ON_PAGE_MAX); i++) {
			pathLength = strlen(buttons[i].text);
			for (j=pathLength; j<(width - 8); j++) {
				buttons[i].text[j] = ' ';
			}
			buttons[i].text[j] = '\0';
			strcpy(&(buttons[i].text[j]), files[currentPageStart+i].date);
			buttons[i].x = x;
			buttons[i].y = y + 1 + i;
		}
		
		if (count > FILES_ON_PAGE_MAX) {
			// Create up and down arrows.
			initializeButton(&(buttons[i]));
			strcpy(buttons[i].text, "     *     ");
			buttons[i].symbol[0] = UP_ARROW_CHAR;
			if (currentPageStart <= 0) {
				buttons[i].flags &= ~(B_ENABLED | B_DRAW);
			} else {
				buttons[i].hotkey[0] = UP_ARROW;
				buttons[i].hotkey[1] = NUMPAD_8;
				buttons[i].hotkey[2] = PAGE_UP_KEY;
			}
			buttons[i].x = x + (width - 11)/2;
			buttons[i].y = y;
			
			i++;
			initializeButton(&(buttons[i]));
			strcpy(buttons[i].text, "     *     ");
			buttons[i].symbol[0] = DOWN_ARROW_CHAR;
			if (currentPageStart + FILES_ON_PAGE_MAX >= count) {
				buttons[i].flags &= ~(B_ENABLED | B_DRAW);
			} else {
				buttons[i].hotkey[0] = DOWN_ARROW;
				buttons[i].hotkey[1] = NUMPAD_2;
				buttons[i].hotkey[2] = PAGE_DOWN_KEY;
			}
			buttons[i].x = x + (width - 11)/2;
			buttons[i].y = y + i;
		}
		
		if (count) {
			clearDisplayBuffer(dbuf);
			printString(prompt, x, y - 1, &itemMessageColor, dialogColor, dbuf);
			rectangularShading(x - 1, y - 1, width + 1, height + 1, dialogColor, INTERFACE_OPACITY, dbuf);
			overlayDisplayBuffer(dbuf, NULL);
			
            //			for (j=0; j<min(count - currentPageStart, FILES_ON_PAGE_MAX); j++) {
            //				printf("\nSanity check BEFORE: %s, with date: %s", files[currentPageStart+j].path, files[currentPageStart+j].date);
            //				printf("\n   (button name)Sanity check BEFORE: %s", buttons[j].text);
            //			}
			
			i = buttonInputLoop(buttons,
								min(count - currentPageStart, FILES_ON_PAGE_MAX) + (count > FILES_ON_PAGE_MAX ? 2 : 0),
								x,
								y,
								width,
								height,
								NULL);
			
            //			for (j=0; j<min(count - currentPageStart, FILES_ON_PAGE_MAX); j++) {
            //				printf("\nSanity check AFTER: %s, with date: %s", files[currentPageStart+j].path, files[currentPageStart+j].date);
            //				printf("\n   (button name)Sanity check AFTER: %s", buttons[j].text);
            //			}
			
			overlayDisplayBuffer(rbuf, NULL);
			
			if (i < min(count - currentPageStart, FILES_ON_PAGE_MAX)) {
				if (i >= 0) {
					retval = true;
					strcpy(path, files[currentPageStart+i].path);
				} else { // i is -1
					retval = false;
				}
			} else if (i == min(count - currentPageStart, FILES_ON_PAGE_MAX)) { // Up arrow
				again = true;
				currentPageStart -= FILES_ON_PAGE_MAX;
			} else if (i == min(count - currentPageStart, FILES_ON_PAGE_MAX) + 1) { // Down arrow
				again = true;
				currentPageStart += FILES_ON_PAGE_MAX;
			}
		}
		
	} while (again);
	
	free(files);
	free(membuf);
	
	if (count == 0) {
		dialogAlert("No applicable files found.");
		return false;
	} else {
		return retval;
	}
}
示例#2
0
boolean dialogChooseFile(char *path, const char *suffix, const char *prompt) {
	short i, j, count, x, y, width, height, suffixLength, pathLength, maxPathLength, currentPageStart;
	brogueButton buttons[FILES_ON_PAGE_MAX + 2];
	fileEntry *files;
	boolean retval = false, again;
	color *dialogColor = &interfaceBoxColor;
	char *membuf;
	
	suffixLength = strlen(suffix);
	files = listFiles(&count, &membuf);
//	copyDisplayBuffer(rbuf, displayBuffer);
	maxPathLength = strLenWithoutEscapes(prompt);
	
	// First, we want to filter the list by stripping out any filenames that do not end with suffix.
	// i is the entry we're testing, and j is the entry that we move it to if it qualifies.
	for (i=0, j=0; i<count; i++) {
		pathLength = strlen(files[i].path);
		//printf("\nString 1: %s", &(files[i].path[(max(0, pathLength - suffixLength))]));
		if (stringsExactlyMatch(&(files[i].path[(max(0, pathLength - suffixLength))]), suffix)) {
			
			// This file counts!
			if (i > j) {
				files[j] = files[i];
				//printf("\nMatching file: %s\twith date: %s", files[j].path, files[j].date);
			}
			j++;
			
			// Keep track of the longest length.
			if (min(pathLength, MAX_FILENAME_DISPLAY_LENGTH) + 10 > maxPathLength) {
				maxPathLength = min(pathLength, MAX_FILENAME_DISPLAY_LENGTH) + 10;
			}
		}
	}
	count = j;
	
	currentPageStart = 0;
	
	do { // Repeat to permit scrolling.
		again = false;
		
		for (i=0; i<min(count - currentPageStart, FILES_ON_PAGE_MAX); i++) {
			initializeButton(&(buttons[i]));
			buttons[i].flags &= ~(B_WIDE_CLICK_AREA | B_GRADIENT);
			buttons[i].buttonColor = *dialogColor;
			sprintf(buttons[i].text, "%c)\t", 'a' + i);
			strncat(buttons[i].text, files[currentPageStart+i].path, MAX_FILENAME_DISPLAY_LENGTH);
			
			// Clip off the file suffix from the button text.
			buttons[i].text[strlen(buttons[i].text) - suffixLength] = '\0'; // Snip!
			buttons[i].hotkey[0] = 'a' + i;
			buttons[i].hotkey[1] = 'A' + i;
			
			// Clip the filename length if necessary.
			if (strlen(buttons[i].text) > MAX_FILENAME_DISPLAY_LENGTH) {
				strcpy(&(buttons[i].text[MAX_FILENAME_DISPLAY_LENGTH - 3]), "...");
			}
			
			//printf("\nFound file: %s, with date: %s", files[currentPageStart+i].path, files[currentPageStart+i].date);
		}
		
		x = (COLS - maxPathLength) / 2;
		width = maxPathLength;
		height = min(count - currentPageStart, FILES_ON_PAGE_MAX) + 5;
		y = max(4, (ROWS - height) / 2);
		
		for (i=0; i<min(count - currentPageStart, FILES_ON_PAGE_MAX); i++) {
			strcat(buttons[i].text, "\t");
			strcat(buttons[i].text, files[currentPageStart+i].date);
			buttons[i].x = 1;
			buttons[i].y = 3 + i;
			buttons[i].width = width;
		}
		
		if (count > FILES_ON_PAGE_MAX) {

			// Create up and down arrows.
			initializeButton(&(buttons[i]));
			strcpy(buttons[i].text, "     *     ");
			buttons[i].symbol[0] = UP_ARROW_CHAR;
			if (currentPageStart <= 0) {
				buttons[i].flags &= ~(B_ENABLED | B_DRAW);
			} else {
				buttons[i].hotkey[0] = UP_ARROW;
				buttons[i].hotkey[1] = NUMPAD_8;
				buttons[i].hotkey[2] = PAGE_UP_KEY;
			}
			buttons[i].x = (width - 11)/2;
			buttons[i].y = 2;
			
			i++;
			initializeButton(&(buttons[i]));
			strcpy(buttons[i].text, "     *     ");
			buttons[i].symbol[0] = DOWN_ARROW_CHAR;
			if (currentPageStart + FILES_ON_PAGE_MAX >= count) {
				buttons[i].flags &= ~(B_ENABLED | B_DRAW);
			} else {
				buttons[i].hotkey[0] = DOWN_ARROW;
				buttons[i].hotkey[1] = NUMPAD_2;
				buttons[i].hotkey[2] = PAGE_DOWN_KEY;
			}
			buttons[i].x = (width - 11)/2;
			buttons[i].y = 2 + i;
		}
		
		if (count) {
			BROGUE_WINDOW *root, *window;
			BROGUE_DRAW_CONTEXT *context;
			BROGUE_EFFECT *effect;
			int tabStops[2] = { 3, width - 8 }; 

			root = ioGetRoot();
			window = BrogueWindow_open(
				root, (COLS - width) / 2, (ROWS - height) / 2, 
				width, height);
			context = BrogueDrawContext_open(window);
			effect = BrogueEffect_open(context, BUTTON_EFFECT_NAME);

			BrogueWindow_setColor(window, windowColor);
			BrogueDrawContext_enableProportionalFont(context, 1);
			BrogueDrawContext_setTabStops(context, 2, tabStops);

			BrogueDrawContext_drawAsciiString(context, 1, 1, prompt);

//			for (j=0; j<min(count - currentPageStart, FILES_ON_PAGE_MAX); j++) {
//				printf("\nSanity check BEFORE: %s, with date: %s", files[currentPageStart+j].path, files[currentPageStart+j].date);
//				printf("\n   (button name)Sanity check BEFORE: %s", buttons[j].text);
//			}
			
			i = buttonInputLoop(buttons,
								min(count - currentPageStart, FILES_ON_PAGE_MAX) + (count > FILES_ON_PAGE_MAX ? 2 : 0),
								context, 
								effect, 
								x,
								y,
								width,
								height,
								NULL); 

			BrogueWindow_close(window);
			
//			for (j=0; j<min(count - currentPageStart, FILES_ON_PAGE_MAX); j++) {
//				printf("\nSanity check AFTER: %s, with date: %s", files[currentPageStart+j].path, files[currentPageStart+j].date);
//				printf("\n   (button name)Sanity check AFTER: %s", buttons[j].text);
//			}

			if (i < min(count - currentPageStart, FILES_ON_PAGE_MAX)) {
				if (i >= 0) {
					retval = true;
					strcpy(path, files[currentPageStart+i].path);
				} else { // i is -1
					retval = false;
				}
			} else if (i == min(count - currentPageStart, FILES_ON_PAGE_MAX)) { // Up arrow
				again = true;
				currentPageStart -= FILES_ON_PAGE_MAX;
			} else if (i == min(count - currentPageStart, FILES_ON_PAGE_MAX) + 1) { // Down arrow
				again = true;
				currentPageStart += FILES_ON_PAGE_MAX;
			}
		}
		
	} while (again);
	
	free(files);
	free(membuf);
	
	if (count == 0) {
		dialogAlert("找不到合适的文件。");
		return false;
	} else {
		return retval;
	}
}