138 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "pch.h"
 | |
| #include "menu.h"
 | |
| 
 | |
| // Checks if a line index should display a menu item
 | |
| bool is_item_line(const int line, const int itemc, int* item_index)
 | |
| {
 | |
| 	if (line >= 2 && line % 2 == 0)
 | |
| 	{
 | |
| 		// Lines 2, 4, ...
 | |
| 		*item_index = (line - 2) / 2;
 | |
| 		return *item_index < itemc;
 | |
| 	}
 | |
| 	return false;
 | |
| }
 | |
| 
 | |
| // Acquires the dimensions (width and height) of the console window
 | |
| void get_console_dimensions(int* width, int* height)
 | |
| {
 | |
| 	CONSOLE_SCREEN_BUFFER_INFO csbi;
 | |
| 
 | |
| 	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
 | |
| 	*width = csbi.srWindow.Right - csbi.srWindow.Left + 1;
 | |
| 	*height = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
 | |
| }
 | |
| 
 | |
| void show_menu(const int itemc, struct MenuItem itemv[], const char title[], bool loopback, bool pause, enum MenuStyle style)
 | |
| {
 | |
| 	unsigned width, height, item_index;
 | |
| 	char key;
 | |
| 	bool action_performed;
 | |
| 
 | |
| 	// Clear the console window
 | |
| 	system("cls");
 | |
| 
 | |
| 	// Get the width and height of the console window
 | |
| 	get_console_dimensions(&width, &height);
 | |
| 	
 | |
| 	// Print frame with title
 | |
| 	for (unsigned i = 0; i < height - 1; ++i)
 | |
| 	{
 | |
| 		// Top line with title
 | |
| 		if (i == 0)
 | |
| 		{
 | |
| 			for (unsigned j = 0; j < width - strlen(title) - 1; ++j)
 | |
| 			{
 | |
| 				if (j == ((width - strlen(title)) - 2)/ 2)
 | |
| 				{
 | |
| 					style == DEFAULT ? putchar('*') : style == MODERN ? putchar('[') : putchar(' ');
 | |
| 					fputs(title, stdout);
 | |
| 					style == DEFAULT ? putchar('*') : style == MODERN ? putchar('[') : putchar(' ');
 | |
| 				}
 | |
| 				else 
 | |
| 				{
 | |
| 					style == DEFAULT ? putchar('*') : style == MODERN ? putchar('-') : putchar(' ');
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		// Line with menu item
 | |
| 		else if (is_item_line(i, itemc, &item_index))
 | |
| 		{
 | |
| 			// Print item text
 | |
| 
 | |
| 			style == DEFAULT ? putchar('*') : style == MODERN ? putchar('|') : putchar(' ');
 | |
| 
 | |
|  			if (strcmp(itemv[item_index].text, "BLANK") == 0) {
 | |
| 				putchar('\t');
 | |
| 
 | |
| 				// BLANK equals 5 characters 
 | |
| 				// + 3 since it regularly is "%c) " inbetween title and key
 | |
| 				for (unsigned j = 0; j < 8; ++j)
 | |
| 				{
 | |
| 					putchar(' ');
 | |
| 				}
 | |
| 			}
 | |
| 			else {
 | |
| 				printf("\t%c) %s", itemv[item_index].key, itemv[item_index].text);
 | |
| 				
 | |
| 			}
 | |
| 			
 | |
| 			// Print right side of frame
 | |
| 			for (unsigned j = 0; j < width - strlen(itemv[item_index].text) - 12; ++j)
 | |
| 			{
 | |
| 				putchar(' ');
 | |
| 			}
 | |
| 			
 | |
| 			style == DEFAULT ? putchar('*') : style == MODERN ? putchar('|') : putchar(' ');
 | |
| 		}
 | |
| 		// Line above bottom line
 | |
| 		else if (i == height - 3)
 | |
| 		{
 | |
| 			for (unsigned j = 0; j < width; ++j)
 | |
| 			{
 | |
| 				style == DEFAULT ? putchar('*') : style == MODERN ? putchar('-') : putchar(' ');
 | |
| 			}
 | |
| 		}
 | |
| 		// Blank line
 | |
| 		else
 | |
| 		{
 | |
| 			i != height - 2 ? style == DEFAULT ? putchar('*') : style == MODERN ? putchar('|') : putchar(' ') : putchar(' ');
 | |
| 			for (unsigned j = 0; j < width - 2; ++j)
 | |
| 			{
 | |
| 				putchar(' ');
 | |
| 			}
 | |
| 			i != height - 2 ? style == DEFAULT ? putchar('*') : style == MODERN ? putchar('|') : putchar(' ') : putchar(' ');
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Wait for user selection
 | |
| 	putchar('>');
 | |
| 	putchar(' ');
 | |
| 	action_performed = false;
 | |
| 	do {
 | |
| 		key = _getch();
 | |
| 		for (int i = 0; i < itemc; ++i)
 | |
| 		{
 | |
| 			if (itemv[i].key == key)
 | |
| 			{
 | |
| 				// Perform action
 | |
| 				system("cls");
 | |
| 				itemv[i].action();
 | |
| 				action_performed = true;
 | |
| 
 | |
| 				// Pause if requested
 | |
| 				if (pause)
 | |
| 				{
 | |
| 					putchar('\n');
 | |
| 					system("pause");
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	} while (!action_performed);
 | |
| 
 | |
| 	// Show menu again if requested
 | |
| 	if (loopback)
 | |
| 	{
 | |
| 		show_menu(itemc, itemv, title, loopback, pause, style);
 | |
| 	}
 | |
| } | 
