2019-12-19 14:51:51 +01:00
|
|
|
#include "pch.h"
|
2019-12-21 20:13:38 +01:00
|
|
|
#include "framework.h"
|
2019-12-19 14:51:51 +01:00
|
|
|
#include "menu.h"
|
|
|
|
|
2020-01-09 09:24:13 +01:00
|
|
|
const struct MenuBorder DEFAULT = {
|
|
|
|
'*', '*', '*', '*', '*', '*', '[', ']'
|
|
|
|
};
|
|
|
|
|
|
|
|
const struct MenuBorder MODERN = {
|
2020-01-09 10:26:03 +01:00
|
|
|
'|', '-', '-', '-', '-', '-', '[', ']'
|
2020-01-09 09:24:13 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const struct MenuBorder NO_BORDER = {
|
|
|
|
' ', ' ', ' ', ' ', ' ' ,' ' ,' ' ,' '
|
|
|
|
};
|
|
|
|
|
|
|
|
const struct MenuBorder SOLID = {
|
|
|
|
186, 205, 201, 187, 200, 188, '[', ']'
|
|
|
|
};
|
|
|
|
|
2019-12-19 14:51:51 +01:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2020-01-09 14:31:00 +01:00
|
|
|
void page(const struct MenuPage *pages, const size_t page_count, const bool infinite_loop) {
|
2020-01-09 14:12:58 +01:00
|
|
|
unsigned int page_index = 0;
|
|
|
|
bool action_performed, loop, pageChanged = true;
|
|
|
|
char pageKey, itemKey;
|
|
|
|
|
|
|
|
do {
|
|
|
|
do {
|
|
|
|
show_menu(pages[page_index].item_count, pages[page_index].items, pages[page_index].title, pages[page_index].border);
|
|
|
|
|
|
|
|
// Wait for user selection
|
|
|
|
putchar('>');
|
|
|
|
putchar(' ');
|
|
|
|
|
|
|
|
loop = pages[page_index].loopback;
|
|
|
|
pageKey = _getch();
|
|
|
|
|
|
|
|
if (pageKey == 'm')
|
|
|
|
page_index < page_count - 1 ? page_index++ : page_index;
|
|
|
|
else if (pageKey == 'n')
|
|
|
|
page_index > 0 ? page_index-- : page_index;
|
|
|
|
else {
|
|
|
|
pageChanged = false;
|
|
|
|
itemKey = pageKey;
|
|
|
|
do {
|
|
|
|
action_performed = false;
|
|
|
|
|
|
|
|
itemKey != pageKey ? itemKey = _getch() : pageKey;
|
|
|
|
pageKey = 0;
|
|
|
|
for (int i = 0; i < pages[page_index].item_count; ++i) {
|
|
|
|
if (pages[page_index].items[i].key == itemKey) {
|
|
|
|
// Perform action
|
|
|
|
system("cls");
|
|
|
|
pages[page_index].items[i].action();
|
|
|
|
action_performed = true;
|
|
|
|
|
|
|
|
// Pause if requested
|
|
|
|
if (pages[page_index].pause) {
|
|
|
|
putchar('\n');
|
|
|
|
system("pause");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} while (!action_performed);
|
|
|
|
}
|
|
|
|
} while (loop || pageChanged);
|
|
|
|
|
|
|
|
page_index = 0;
|
2020-01-09 14:31:00 +01:00
|
|
|
} while (infinite_loop);
|
2020-01-09 14:12:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void show_menu(const int itemc, const struct MenuItem itemv[], const char title[], const struct MenuBorder *border)
|
2019-12-19 14:51:51 +01:00
|
|
|
{
|
|
|
|
unsigned width, height, item_index;
|
|
|
|
|
|
|
|
// Clear the console window
|
|
|
|
system("cls");
|
|
|
|
|
|
|
|
// Get the width and height of the console window
|
|
|
|
get_console_dimensions(&width, &height);
|
2019-12-21 19:53:19 +01:00
|
|
|
|
2019-12-19 14:51:51 +01:00
|
|
|
// Print frame with title
|
|
|
|
for (unsigned i = 0; i < height - 1; ++i)
|
|
|
|
{
|
|
|
|
// Top line with title
|
|
|
|
if (i == 0)
|
|
|
|
{
|
2020-01-09 09:24:13 +01:00
|
|
|
// Upper left corner
|
|
|
|
putchar(border->corner_upper_left);
|
|
|
|
|
|
|
|
for (unsigned j = 1; j < width - strlen(title) - 2; ++j)
|
2019-12-19 14:51:51 +01:00
|
|
|
{
|
2019-12-21 19:53:19 +01:00
|
|
|
if (j == ((width - strlen(title)) - 2)/ 2)
|
2019-12-19 14:51:51 +01:00
|
|
|
{
|
2020-01-09 09:24:13 +01:00
|
|
|
putchar(border->title_left);
|
2019-12-19 14:51:51 +01:00
|
|
|
fputs(title, stdout);
|
2020-01-09 09:24:13 +01:00
|
|
|
putchar(border->title_right);
|
2019-12-19 14:51:51 +01:00
|
|
|
}
|
2019-12-21 19:53:19 +01:00
|
|
|
else
|
2019-12-19 14:51:51 +01:00
|
|
|
{
|
2020-01-09 09:24:13 +01:00
|
|
|
putchar(border->line_horizontal);
|
2019-12-19 14:51:51 +01:00
|
|
|
}
|
|
|
|
}
|
2020-01-09 09:24:13 +01:00
|
|
|
|
|
|
|
// Upper right corner
|
|
|
|
putchar(border->corner_upper_right);
|
2019-12-19 14:51:51 +01:00
|
|
|
}
|
|
|
|
// Line with menu item
|
|
|
|
else if (is_item_line(i, itemc, &item_index))
|
|
|
|
{
|
|
|
|
// Print item text
|
2020-01-09 09:24:13 +01:00
|
|
|
putchar(border->line_vertical);
|
2019-12-21 19:53:19 +01:00
|
|
|
|
|
|
|
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(' ');
|
|
|
|
}
|
|
|
|
}
|
2020-01-09 09:24:13 +01:00
|
|
|
else
|
|
|
|
{
|
2019-12-21 19:53:19 +01:00
|
|
|
printf("\t%c) %s", itemv[item_index].key, itemv[item_index].text);
|
|
|
|
}
|
|
|
|
|
2019-12-19 14:51:51 +01:00
|
|
|
// Print right side of frame
|
|
|
|
for (unsigned j = 0; j < width - strlen(itemv[item_index].text) - 12; ++j)
|
|
|
|
{
|
|
|
|
putchar(' ');
|
|
|
|
}
|
2019-12-21 19:53:19 +01:00
|
|
|
|
2020-01-09 09:24:13 +01:00
|
|
|
putchar(border->line_vertical);
|
2019-12-19 14:51:51 +01:00
|
|
|
}
|
|
|
|
// Line above bottom line
|
2019-12-21 19:53:19 +01:00
|
|
|
else if (i == height - 3)
|
2019-12-19 14:51:51 +01:00
|
|
|
{
|
2020-01-09 09:24:13 +01:00
|
|
|
// Lower left corner
|
|
|
|
putchar(border->corner_lower_left);
|
|
|
|
|
|
|
|
for (unsigned j = 1; j < width - 1; ++j)
|
2019-12-19 14:51:51 +01:00
|
|
|
{
|
2020-01-09 09:24:13 +01:00
|
|
|
putchar(border->line_horizontal);
|
2019-12-19 14:51:51 +01:00
|
|
|
}
|
2020-01-09 09:24:13 +01:00
|
|
|
|
|
|
|
// Lower right corner
|
|
|
|
putchar(border->corner_lower_right);
|
2019-12-19 14:51:51 +01:00
|
|
|
}
|
|
|
|
// Blank line
|
|
|
|
else
|
|
|
|
{
|
2020-01-09 09:24:13 +01:00
|
|
|
i != height - 2 ? putchar(border->line_vertical) : putchar(' ');
|
2019-12-19 14:51:51 +01:00
|
|
|
for (unsigned j = 0; j < width - 2; ++j)
|
|
|
|
{
|
|
|
|
putchar(' ');
|
|
|
|
}
|
2020-01-09 09:24:13 +01:00
|
|
|
i != height - 2 ? putchar(border->line_vertical) : putchar(' ');
|
2019-12-19 14:51:51 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|