std::string Menu::display_stub_default;
display_f Menu::display;
void Menu::entries_t::insert(const std::string &code,
const std::string &prompt, callback_f callback) {
char *buffer = new char[prompt.size() + 1];
strcpy(buffer, prompt.c_str());
items.emplace_back(callback, buffer);
codes.emplace_back(code, prompt);
}
const std::string &Menu::getCode(std::size_t idx) const {
return entries.codes[idx].code;
}
const std::string &Menu::getPrompt(std::size_t idx) const {
return entries.codes[idx].prompt;
}
callback_f Menu::getCallback(std::size_t idx) const {
return entries.items[idx].callback;
}
void Menu::read(const std::string &s) {
std::string line, delim, code, prompt;
std::fstream fs(s);
char tmp = 0;
auto last = menu_lookup.end();
while (std::getline(fs, line)) {
if (line.empty()) continue;
std::istringstream ss(line);
ss >> delim >> code;
ss.ignore(1, ' '), std::getline(ss, prompt);
if (delim == "+") {
ss >> delim >> code >> std::ws;
std::getline(ss, prompt);
if (delim != "+") last->second.entries.insert(code, prompt);
else {
const auto [iter, succ] = menu_lookup.emplace(
std::piecewise_construct, std::forward_as_tuple(code),
std::forward_as_tuple(private_ctor_t{}, code, prompt));
last = iter;
} else {
last->second.entries.insert(code, prompt);
}
}
}
void Menu::print(const std::string &code, const int depth) {
const auto it = menu_lookup.find(code);
if (it == menu_lookup.end()) return;
const Menu *menu = &it->second;
if (depth == 1) std::cout << std::format("{}({})\n", menu->title, code);
for (int i = 0; i < menu->getSize(); i++) {
std::cout << std::string(depth << 1, ' ');
std::cout << menu->getPrompt(i);
std::cout << std::format(" ({})\n", menu->getCode(i));
menu->print(code, depth + 1);
}
}
int Menu::display_stub(int idx) {
static std::deque<const Menu *> st;
const std::string &code =
st.size() ? st.back()->getCode(idx) : display_stub_default;
!st.empty() ? st.back()->getCode(idx) : display_stub_default;
const auto ml_it = menu_lookup.find(code);
if (ml_it != menu_lookup.end()) {