menu.cpp (2219B)
1 #include "menu.hpp" 2 3 #include <deque> 4 #include <format> 5 #include <fstream> 6 #include <iostream> 7 #include <sstream> 8 #include <tuple> 9 #include <utility> 10 11 namespace stamen { 12 namespace menu { 13 14 std::unordered_map<std::string, menu_t> menu_lookup; 15 std::unordered_map<std::string, callback_f> free_lookup; 16 std::string display_stub_default; 17 display_f display; 18 19 void read(const char *filename) { 20 std::string line, delim, code, prompt; 21 std::fstream fs(filename); 22 23 auto last = menu_lookup.end(); 24 while (std::getline(fs, line)) { 25 if (line.empty()) continue; 26 27 std::istringstream ss(line); 28 ss >> delim >> code >> std::ws; 29 std::getline(ss, prompt); 30 31 if (delim != "+") last->second.insert(code, prompt); 32 else { 33 const auto [iter, succ] = menu_lookup.emplace( 34 std::piecewise_construct, std::forward_as_tuple(code), 35 std::forward_as_tuple(menu_t::private_ctor_t{}, code, prompt)); 36 last = iter; 37 } 38 } 39 } 40 41 void insert(const char *code, callback_f callback) { 42 free_lookup.emplace(code, callback); 43 } 44 45 int dynamic(const char *code, display_f display) { 46 menu::display_stub_default = code; 47 menu::display = display; 48 return display_stub(-1); 49 } 50 51 int display_stub(int idx) { 52 static std::deque<const menu_t *> st; 53 54 const std::string &code = 55 !st.empty() ? st.back()->getCode(idx) : display_stub_default; 56 57 const auto ml_it = menu_lookup.find(code); 58 if (ml_it != menu_lookup.end()) { 59 const auto &m = ml_it->second; 60 61 st.push_back(&m); 62 int ret = display(m.getTitle().c_str(), m.getItemv(), m.getSize()); 63 st.pop_back(); 64 65 return ret; 66 } 67 68 const auto fl_it = free_lookup.find(code); 69 if (fl_it != free_lookup.end()) return fl_it->second(0); 70 71 std::cout << "Stamen: nothing to do..." << std::endl; 72 return 1; 73 } 74 75 void menu_t::insert(const std::string &code, const std::string &prompt, 76 callback_f callback) { 77 char *buffer = new char[prompt.size() + 1]; 78 strcpy(buffer, prompt.c_str()); 79 80 items.emplace_back(callback, buffer); 81 codes.emplace_back(code, prompt); 82 } 83 84 } // namespace menu 85 } // namespace stamen