Added paging

- Navigation via 'm' and 'n'
This commit is contained in:
Simon 2020-01-09 14:12:58 +01:00
parent 99fd6d468b
commit 54fbed8330
2 changed files with 66 additions and 38 deletions

85
menu.c
View File

@ -40,11 +40,59 @@ void get_console_dimensions(int* width, int* height)
*height = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; *height = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
} }
void show_menu(const int itemc, const struct MenuItem itemv[], const char title[], const bool loopback, const bool pause, const struct MenuBorder *border) void page(const struct MenuPage *pages, const size_t page_count) {
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;
} while (1);
}
void show_menu(const int itemc, const struct MenuItem itemv[], const char title[], const struct MenuBorder *border)
{ {
unsigned width, height, item_index; unsigned width, height, item_index;
char key;
bool action_performed;
// Clear the console window // Clear the console window
system("cls"); system("cls");
@ -132,35 +180,4 @@ void show_menu(const int itemc, const struct MenuItem itemv[], const char title[
i != height - 2 ? putchar(border->line_vertical) : putchar(' '); i != height - 2 ? putchar(border->line_vertical) : 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, border);
}
} }

19
menu.h
View File

@ -2,6 +2,8 @@
#include "pch.h" #include "pch.h"
/// <summary>Represents one menu item in a menu.</summary> /// <summary>Represents one menu item in a menu.</summary>
struct MenuItem { struct MenuItem {
char* text; char* text;
@ -9,6 +11,8 @@ struct MenuItem {
void* (*action)(void); void* (*action)(void);
}; };
/// <summary>Represents a border in which a menu is displayed.</summary> /// <summary>Represents a border in which a menu is displayed.</summary>
struct MenuBorder { struct MenuBorder {
char line_vertical; char line_vertical;
@ -23,11 +27,18 @@ struct MenuBorder {
const extern struct MenuBorder DEFAULT, MODERN, NO_BORDER, SOLID; const extern struct MenuBorder DEFAULT, MODERN, NO_BORDER, SOLID;
/// <summary>Displaces a CUI menu to the user and lets them choose an option, then calls the corresponding function.</summary> /// <summary>Represents a page in the menu.</summary>
struct MenuPage {
const struct MenuItem* items;
const size_t item_count;
char* title;
bool loopback, pause;
const struct MenuBorder* border;
};
/// <summary>Displaces a CUI menu to the user</summary>
/// <param name="itemc">The length of the array <c>itemv</c> of menu items.</param> /// <param name="itemc">The length of the array <c>itemv</c> of menu items.</param>
/// <param name="itemv">An array of all menu items to display in the menu.</param> /// <param name="itemv">An array of all menu items to display in the menu.</param>
/// <param name="title">The title of the menu.</param> /// <param name="title">The title of the menu.</param>
/// <param name="loopback">If this parameter is set to <c>true</c>, the menu will be displayed again after an action is executed.</param>
/// <param name="pause">If this parameter is set to <c>true</c>, a <c>pause</c>command will be run after an action is executed.</param>
/// <param name="border">Specifies the border in which the menu is displayed.</param> /// <param name="border">Specifies the border in which the menu is displayed.</param>
void show_menu(const int itemc, const struct MenuItem itemv[], const char title[], const bool loopback, const bool pause, const struct MenuBorder *border); void show_menu(const int itemc, const struct MenuItem itemv[], const char title[], const struct MenuBorder *border);