From 54fbed833005cf4933108160a0175df4d42f5df7 Mon Sep 17 00:00:00 2001
From: Simon <33755707+Crotex@users.noreply.github.com>
Date: Thu, 9 Jan 2020 14:12:58 +0100
Subject: [PATCH 1/3] Added paging
- Navigation via 'm' and 'n'
---
menu.c | 85 +++++++++++++++++++++++++++++++++++-----------------------
menu.h | 19 ++++++++++---
2 files changed, 66 insertions(+), 38 deletions(-)
diff --git a/menu.c b/menu.c
index c516898..982c135 100644
--- a/menu.c
+++ b/menu.c
@@ -40,11 +40,59 @@ void get_console_dimensions(int* width, int* height)
*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;
- char key;
- bool action_performed;
// Clear the console window
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(' ');
}
}
-
- // 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);
- }
}
\ No newline at end of file
diff --git a/menu.h b/menu.h
index 67c905a..92981a7 100644
--- a/menu.h
+++ b/menu.h
@@ -2,6 +2,8 @@
#include "pch.h"
+
+
/// Represents one menu item in a menu.
struct MenuItem {
char* text;
@@ -9,6 +11,8 @@ struct MenuItem {
void* (*action)(void);
};
+
+
/// Represents a border in which a menu is displayed.
struct MenuBorder {
char line_vertical;
@@ -23,11 +27,18 @@ struct MenuBorder {
const extern struct MenuBorder DEFAULT, MODERN, NO_BORDER, SOLID;
-/// Displaces a CUI menu to the user and lets them choose an option, then calls the corresponding function.
+/// Represents a page in the menu.
+struct MenuPage {
+ const struct MenuItem* items;
+ const size_t item_count;
+ char* title;
+ bool loopback, pause;
+ const struct MenuBorder* border;
+};
+
+/// Displaces a CUI menu to the user
/// The length of the array itemv of menu items.
/// An array of all menu items to display in the menu.
/// The title of the menu.
-/// If this parameter is set to true, the menu will be displayed again after an action is executed.
-/// If this parameter is set to true, a pausecommand will be run after an action is executed.
/// Specifies the border in which the menu is displayed.
-void show_menu(const int itemc, const struct MenuItem itemv[], const char title[], const bool loopback, const bool pause, const struct MenuBorder *border);
\ No newline at end of file
+void show_menu(const int itemc, const struct MenuItem itemv[], const char title[], const struct MenuBorder *border);
\ No newline at end of file
From 72046f2e0c7d475d938d166a5fe2987bb42344a7 Mon Sep 17 00:00:00 2001
From: Simon <33755707+Crotex@users.noreply.github.com>
Date: Thu, 9 Jan 2020 14:31:00 +0100
Subject: [PATCH 2/3] Added paging
Fixes #2
---
menu.c | 4 ++--
menu.h | 11 ++++++++---
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/menu.c b/menu.c
index 982c135..721e23d 100644
--- a/menu.c
+++ b/menu.c
@@ -40,7 +40,7 @@ void get_console_dimensions(int* width, int* height)
*height = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
}
-void page(const struct MenuPage *pages, const size_t page_count) {
+void page(const struct MenuPage *pages, const size_t page_count, const bool infinite_loop) {
unsigned int page_index = 0;
bool action_performed, loop, pageChanged = true;
char pageKey, itemKey;
@@ -87,7 +87,7 @@ void page(const struct MenuPage *pages, const size_t page_count) {
} while (loop || pageChanged);
page_index = 0;
- } while (1);
+ } while (infinite_loop);
}
void show_menu(const int itemc, const struct MenuItem itemv[], const char title[], const struct MenuBorder *border)
diff --git a/menu.h b/menu.h
index 92981a7..63d3845 100644
--- a/menu.h
+++ b/menu.h
@@ -3,7 +3,6 @@
#include "pch.h"
-
/// Represents one menu item in a menu.
struct MenuItem {
char* text;
@@ -11,8 +10,6 @@ struct MenuItem {
void* (*action)(void);
};
-
-
/// Represents a border in which a menu is displayed.
struct MenuBorder {
char line_vertical;
@@ -27,6 +24,7 @@ struct MenuBorder {
const extern struct MenuBorder DEFAULT, MODERN, NO_BORDER, SOLID;
+
/// Represents a page in the menu.
struct MenuPage {
const struct MenuItem* items;
@@ -36,6 +34,13 @@ struct MenuPage {
const struct MenuBorder* border;
};
+
+/// Constructs a menu with a specific amount of pages
+/// An array of all pages to display.
+/// The length of the array pages.
+/// Always display the first page after a loopback=false item finished executing.
+void page(const struct MenuPage* pages, const size_t page_count, const bool infinite_loop);
+
/// Displaces a CUI menu to the user
/// The length of the array itemv of menu items.
/// An array of all menu items to display in the menu.
From 9f5b615df917c65a46c748c74ece3b44c536908f Mon Sep 17 00:00:00 2001
From: CyB3RC0nN0R
Date: Tue, 14 Jan 2020 08:12:36 +0100
Subject: [PATCH 3/3] Removed show_menu from menu.h, simplified some code
---
menu.c | 126 +++++++++++++++++++++++++++++++--------------------------
menu.h | 17 ++------
2 files changed, 73 insertions(+), 70 deletions(-)
diff --git a/menu.c b/menu.c
index 721e23d..7e51057 100644
--- a/menu.c
+++ b/menu.c
@@ -1,5 +1,6 @@
#include "pch.h"
#include "framework.h"
+
#include "menu.h"
const struct MenuBorder DEFAULT = {
@@ -18,6 +19,66 @@ const struct MenuBorder SOLID = {
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
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;
}
-void page(const struct MenuPage *pages, const size_t page_count, const bool infinite_loop) {
- 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 (infinite_loop);
-}
-
-void show_menu(const int itemc, const struct MenuItem itemv[], const char title[], const struct MenuBorder *border)
+// Draws a menu to the console
+void show_menu(const int itemc, const struct MenuItem itemv[], const char title[], const struct MenuBorder* border)
{
unsigned width, height, item_index;
@@ -99,7 +111,7 @@ void show_menu(const int itemc, const struct MenuItem itemv[], const char title[
// 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)
{
@@ -111,13 +123,13 @@ void show_menu(const int itemc, const struct MenuItem itemv[], const char title[
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);
fputs(title, stdout);
putchar(border->title_right);
}
- else
+ else
{
putchar(border->line_horizontal);
}
@@ -132,7 +144,7 @@ void show_menu(const int itemc, const struct MenuItem itemv[], const char title[
// Print item text
putchar(border->line_vertical);
- if (strcmp(itemv[item_index].text, "BLANK") == 0) {
+ if (strcmp(itemv[item_index].text, "BLANK") == 0) {
putchar('\t');
// BLANK equals 5 characters
@@ -146,13 +158,13 @@ void show_menu(const int itemc, const struct MenuItem itemv[], const char title[
{
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(' ');
}
-
+
putchar(border->line_vertical);
}
// Line above bottom line
diff --git a/menu.h b/menu.h
index 63d3845..cb210ad 100644
--- a/menu.h
+++ b/menu.h
@@ -2,7 +2,6 @@
#include "pch.h"
-
/// Represents one menu item in a menu.
struct MenuItem {
char* text;
@@ -22,10 +21,10 @@ struct MenuBorder {
char title_right;
};
+// Default borders initialized in menu.c
const extern struct MenuBorder DEFAULT, MODERN, NO_BORDER, SOLID;
-
-/// Represents a page in the menu.
+/// Represents a page containing menu items inside a menu.
struct MenuPage {
const struct MenuItem* items;
const size_t item_count;
@@ -34,16 +33,8 @@ struct MenuPage {
const struct MenuBorder* border;
};
-
-/// Constructs a menu with a specific amount of pages
+/// Constructs a CUI menu with a specific amount of pages.
/// An array of all pages to display.
/// The length of the array pages.
/// Always display the first page after a loopback=false item finished executing.
-void page(const struct MenuPage* pages, const size_t page_count, const bool infinite_loop);
-
-/// Displaces a CUI menu to the user
-/// The length of the array itemv of menu items.
-/// An array of all menu items to display in the menu.
-/// The title of the menu.
-/// Specifies the border in which the menu is displayed.
-void show_menu(const int itemc, const struct MenuItem itemv[], const char title[], const struct MenuBorder *border);
\ No newline at end of file
+void page(const struct MenuPage* pages, const size_t page_count, const bool infinite_loop);
\ No newline at end of file