Removed show_menu from menu.h, simplified some code
This commit is contained in:
parent
72046f2e0c
commit
9f5b615df9
116
menu.c
116
menu.c
@ -1,5 +1,6 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
|
||||||
const struct MenuBorder DEFAULT = {
|
const struct MenuBorder DEFAULT = {
|
||||||
@ -18,6 +19,66 @@ const struct MenuBorder SOLID = {
|
|||||||
186, 205, 201, 187, 200, 188, '[', ']'
|
186, 205, 201, 187, 200, 188, '[', ']'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void show_menu(const int itemc, const struct MenuItem itemv[], const char title[], const struct MenuBorder* border);
|
||||||
|
|
||||||
|
void page(const struct MenuPage* pages, const size_t page_count, const bool infinite_loop)
|
||||||
|
{
|
||||||
|
unsigned int page_index = 0;
|
||||||
|
bool action_performed, loop, page_changed = true;
|
||||||
|
char page_key, itemKey;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
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;
|
||||||
|
page_key = _getch();
|
||||||
|
|
||||||
|
// Forward paging
|
||||||
|
if (page_key == 'm' && page_index < page_count - 1)
|
||||||
|
++page_index;
|
||||||
|
// Backward paging
|
||||||
|
else if (page_key == 'n' && page_index > 0)
|
||||||
|
--page_index;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
page_changed = false;
|
||||||
|
itemKey = page_key;
|
||||||
|
do {
|
||||||
|
action_performed = false;
|
||||||
|
|
||||||
|
itemKey != page_key ? itemKey = _getch() : page_key;
|
||||||
|
page_key = 0;
|
||||||
|
for (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 || page_changed);
|
||||||
|
|
||||||
|
page_index = 0;
|
||||||
|
} while (infinite_loop);
|
||||||
|
}
|
||||||
|
|
||||||
// Checks if a line index should display a menu item
|
// Checks if a line index should display a menu item
|
||||||
bool is_item_line(const int line, const int itemc, int* item_index)
|
bool is_item_line(const int line, const int itemc, int* item_index)
|
||||||
{
|
{
|
||||||
@ -40,57 +101,8 @@ 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 page(const struct MenuPage *pages, const size_t page_count, const bool infinite_loop) {
|
// Draws a menu to the console
|
||||||
unsigned int page_index = 0;
|
void show_menu(const int itemc, const struct MenuItem itemv[], const char title[], const struct MenuBorder* border)
|
||||||
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 (infinite_loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@ -111,7 +123,7 @@ void show_menu(const int itemc, const struct MenuItem itemv[], const char title[
|
|||||||
|
|
||||||
for (unsigned j = 1; j < width - strlen(title) - 2; ++j)
|
for (unsigned j = 1; j < width - strlen(title) - 2; ++j)
|
||||||
{
|
{
|
||||||
if (j == ((width - strlen(title)) - 2)/ 2)
|
if (j == ((width - strlen(title)) - 2) / 2)
|
||||||
{
|
{
|
||||||
putchar(border->title_left);
|
putchar(border->title_left);
|
||||||
fputs(title, stdout);
|
fputs(title, stdout);
|
||||||
|
15
menu.h
15
menu.h
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#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;
|
||||||
@ -22,10 +21,10 @@ struct MenuBorder {
|
|||||||
char title_right;
|
char title_right;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Default borders initialized in menu.c
|
||||||
const extern struct MenuBorder DEFAULT, MODERN, NO_BORDER, SOLID;
|
const extern struct MenuBorder DEFAULT, MODERN, NO_BORDER, SOLID;
|
||||||
|
|
||||||
|
/// <summary>Represents a page containing menu items inside a menu.</summary>
|
||||||
/// <summary>Represents a page in the menu.</summary>
|
|
||||||
struct MenuPage {
|
struct MenuPage {
|
||||||
const struct MenuItem* items;
|
const struct MenuItem* items;
|
||||||
const size_t item_count;
|
const size_t item_count;
|
||||||
@ -34,16 +33,8 @@ struct MenuPage {
|
|||||||
const struct MenuBorder* border;
|
const struct MenuBorder* border;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// <summary>Constructs a CUI menu with a specific amount of pages.</summary>
|
||||||
/// <summary>Constructs a menu with a specific amount of pages</summary>
|
|
||||||
/// <param name="pages">An array of all pages to display.</param>
|
/// <param name="pages">An array of all pages to display.</param>
|
||||||
/// <param name="page_count">The length of the array <c>pages</c>.</param>
|
/// <param name="page_count">The length of the array <c>pages</c>.</param>
|
||||||
/// <param name="infinite_loop">Always display the first page after a loopback=false item finished executing.</param>
|
/// <param name="infinite_loop">Always display the first page after a loopback=false item finished executing.</param>
|
||||||
void page(const struct MenuPage* pages, const size_t page_count, const bool infinite_loop);
|
void page(const struct MenuPage* pages, const size_t page_count, const bool infinite_loop);
|
||||||
|
|
||||||
/// <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="itemv">An array of all menu items to display in the menu.</param>
|
|
||||||
/// <param name="title">The title of the menu.</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 struct MenuBorder *border);
|
|
Reference in New Issue
Block a user