stamen

Stamen - static menu generator
git clone git://git.dimitrijedobrota.com/stamen.git
Log | Files | Refs | README | LICENSE

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