stamenStatic Menu Generator |
git clone git://git.dimitrijedobrota.com/stamen.git |
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING |
menu.cpp (2281B)
0 #include <deque>
1 #include <format>
2 #include <fstream>
3 #include <iostream>
4 #include <sstream>
5 #include <tuple>
6 #include <utility>
8 #include "stamen/menu.hpp"
10 namespace stamen::menu {
12 // NOLINTBEGIN
13 std::unordered_map<std::string, menu_t> menu_lookup;
14 std::unordered_map<std::string, callback_f> free_lookup;
15 std::string display_stub_default;
16 display_f display;
17 // NOLINTEND
19 void read(const char* filename)
20 {
21 std::fstream fst(filename);
22 std::string line;
23 std::string delim;
24 std::string code;
25 std::string prompt;
27 auto last = menu_lookup.end();
28 while (std::getline(fst, line))
29 {
30 if (line.empty()) continue;
32 std::istringstream iss(line);
33 iss >> delim >> code >> std::ws;
34 std::getline(iss, prompt);
36 if (delim != "+") last->second.insert(code, prompt);
37 else
38 {
39 const auto [iter, succ] = menu_lookup.emplace(
40 std::piecewise_construct,
41 std::forward_as_tuple(code),
42 std::forward_as_tuple(menu_t::private_ctor_t {}, code, prompt));
43 last = iter;
44 }
45 }
46 }
48 void insert(const char* code, callback_f callback)
49 {
50 free_lookup.emplace(code, callback);
51 }
53 int dynamic(const char* code, display_f disp)
54 {
55 menu::display_stub_default = code;
56 menu::display = disp;
57 return display_stub(0);
58 }
60 int display_stub(std::size_t idx)
61 {
62 static std::deque<const menu_t*> stack;
64 const std::string& code =
65 !stack.empty() ? stack.back()->get_code(idx) : display_stub_default;
67 const auto ml_it = menu_lookup.find(code);
68 if (ml_it != menu_lookup.end())
69 {
70 const auto& m = ml_it->second; // NOLINT
72 stack.push_back(&m);
73 const int ret =
74 display(m.get_title().c_str(), m.get_itemv(), m.get_size());
75 stack.pop_back();
77 return ret;
78 }
80 const auto fl_it = free_lookup.find(code);
81 if (fl_it != free_lookup.end()) return fl_it->second(0);
83 std::cout << "Stamen: nothing to do..." << std::endl;
84 return 1;
85 }
87 void menu_t::insert(const std::string& code,
88 const std::string& prompt,
89 callback_f callback)
90 {
91 char* buffer = new char[prompt.size() + 1]; // NOLINT
92 strcpy(buffer, prompt.c_str()); // NOLINT
94 m_items.emplace_back(callback, buffer);
95 m_codes.emplace_back(code, prompt);
96 }
98 } // namespace stamen::menu