stamen

Static Menu Generator
git clone git://git.dimitrijedobrota.com/stamen.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING |

commita0f03cd75241bbb601e1b2eb7abbaa392ea9a3d1
parent4edb0a625526b7b14e16275f2defa4a4a66b83e4
authorDimitrije Dobrota <mail@dimitrijedobrota.com>
dateThu, 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:
M.gitignore|++
MCMakeLists.txt|+-
Mdemo/main.cpp|++++--
Minclude/menu.h|++++++++++++++++---------
Msrc/generate.cpp|++
Msrc/menu.cpp|+++++----

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) {