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> 7 8 #include "stamen/menu.hpp" 9 10 namespace stamen::menu { 11 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 18 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; 26 27 auto last = menu_lookup.end(); 28 while (std::getline(fst, line)) 29 { 30 if (line.empty()) continue; 31 32 std::istringstream iss(line); 33 iss >> delim >> code >> std::ws; 34 std::getline(iss, prompt); 35 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 } 47 48 void insert(const char* code, callback_f callback) 49 { 50 free_lookup.emplace(code, callback); 51 } 52 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 } 59 60 int display_stub(std::size_t idx) 61 { 62 static std::deque<const menu_t*> stack; 63 64 const std::string& code = 65 !stack.empty() ? stack.back()->get_code(idx) : display_stub_default; 66 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 71 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(); 76 77 return ret; 78 } 79 80 const auto fl_it = free_lookup.find(code); 81 if (fl_it != free_lookup.end()) return fl_it->second(0); 82 83 std::cout << "Stamen: nothing to do..." << std::endl; 84 return 1; 85 } 86 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 93 94 m_items.emplace_back(callback, buffer); 95 m_codes.emplace_back(code, prompt); 96 } 97 98 } // namespace stamen::menu