commit a0f03cd75241bbb601e1b2eb7abbaa392ea9a3d1
parent 4edb0a625526b7b14e16275f2defa4a4a66b83e4
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Thu, 16 Nov 2023 13:08:23 +0000
Small Improvements
* Users are required to set display function at compile time
* Ditched default entry
* Improve the interface
Diffstat:
6 files changed, 30 insertions(+), 16 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,2 +1,4 @@
build
.cache
+demo/demo_menu.cpp
+demo/demo_menu.h
diff --git a/CMakeLists.txt b/CMakeLists.txt
@@ -3,7 +3,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(
Menu
- VERSION 0.0.5
+ VERSION 0.0.6
DESCRIPTION "Experimentation with dinamic menus"
LANGUAGES CXX
)
diff --git a/demo/main.cpp b/demo/main.cpp
@@ -2,6 +2,8 @@
#include "demo_menu.h"
+const Menu::display_f Menu::display = Menu::builtinDisplay;
+
int operation(void) {
std::cout << "operation" << std::endl;
std::cout << "Some operation is done" << std::endl;
@@ -14,10 +16,10 @@ int finish(void) {
}
int menu_static_run(void) { return menu::menu_main(); }
-int menu_dynamic_run(void) { return Menu::start(); }
+int menu_dynamic_run(void) { return Menu::start("menu_main"); }
int menu_dynamic_print(void) {
- Menu::print();
+ Menu::print("menu_main");
return 1;
}
diff --git a/include/menu.h b/include/menu.h
@@ -28,18 +28,21 @@ public:
};
struct item_t {
- const std::string prompt, code;
- callback_f callback = nullptr;
-
- item_t(const std::string &code, const std::string &prompt)
- : code(code), prompt(prompt) {}
+ friend class Menu;
item_t(const callback_f func, const std::string &prompt)
: callback(func), prompt(prompt) {}
+ private:
int operator()(void) const {
return callback ? callback() : getMenu(code)();
}
+
+ item_t(const std::string &code, const std::string &prompt)
+ : code(code), prompt(prompt) {}
+
+ const std::string prompt, code;
+ callback_f callback = nullptr;
};
static void read(const std::string &s) {
@@ -65,19 +68,23 @@ public:
}
}
- static int start() { return getMenu(entry)(); }
+ static int start(const std::string &entry) { return getMenu(entry)(); }
static void insert(const std::string &code, const callback_f callback) {
// lookup.emplace(std::piecewise_construct, std::forward_as_tuple(code),
// std::forward_as_tuple(code, callback));
lookup.insert({code, Menu(code, callback)});
}
- static void print(const std::string &code = entry, const int depth = 1);
+ static void print(const std::string &entry) { print(entry, 1); }
static void generateSource(std::ostream &os);
static void generateInclude(std::ostream &os);
- static int display(const std::string &name, const item_t items[], int size);
+ typedef int (*display_f)(const std::string &name, const item_t items[],
+ std::size_t size);
+ static const display_f display;
+ static int builtinDisplay(const std::string &name, const item_t items[],
+ std::size_t size);
int operator()() const {
return callback ? callback() : display(title, items.data(), items.size());
@@ -92,8 +99,8 @@ private:
typedef std::unordered_map<std::string, Menu> lookup_t;
static lookup_t lookup;
- static const std::string entry;
+ static void print(const std::string &entry, const int depth);
static const Menu &getMenu(const std::string &code) {
const auto it = lookup.find(code);
if (it == lookup.end()) throw EMenu();
diff --git a/src/generate.cpp b/src/generate.cpp
@@ -1,6 +1,8 @@
#include "menu.h"
#include <string>
+const Menu::display_f Menu::display = Menu::builtinDisplay;
+
int main(const int argc, const char *argv[]) {
if (argc != 2) {
std::cout << "please enter at exaclty one config file" << std::endl;
diff --git a/src/menu.cpp b/src/menu.cpp
@@ -8,9 +8,9 @@
#include <unordered_set>
std::unordered_map<std::string, Menu> Menu::lookup;
-const std::string Menu::entry = "menu_main";
-int Menu::display(const std::string &name, const item_t items[], int size) {
+int Menu::builtinDisplay(const std::string &name, const item_t items[],
+ std::size_t size) {
int choice;
const int digits = std::log10(size) + 1;
while (true) {
@@ -23,7 +23,7 @@ int Menu::display(const std::string &name, const item_t items[], int size) {
std::cout << "Choose an option: ";
if (std::cin >> choice && choice >= -1 && choice < size) {
if (choice == -1) {
- std::cout << "choice: back\n";
+ std::cout << "Choice: back\n";
return 1;
}
@@ -47,6 +47,7 @@ int Menu::display(const std::string &name, const item_t items[], int size) {
return 1;
}
+
void Menu::generateInclude(std::ostream &os) {
os << "#include \"menu.h\"\n\n";
os << "namespace menu {\n\n";
@@ -85,7 +86,7 @@ void Menu::print(const std::string &code, const int depth) {
if (it == lookup.end()) return;
const Menu &menu = it->second;
- if (depth == 1) { std::cout << std::format("{}({})\n", menu.title, code); }
+ if (depth == 1) std::cout << std::format("{}({})\n", menu.title, code);
if (!menu.callback) {
for (const auto &item : menu.items) {