1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
#include "menu.hh"
#include "screen.hh"
#include "texture.hh"
#include "fs.hh"
MenuOption::MenuOption(std::string const& nm, std::string const& comm, MenuImage img):
type(), value(), newValue(), callback(), image(img), name(nm), comment(comm), namePtr(), commentPtr()
{}
std::string MenuOption::getName() const {
if (namePtr) return *namePtr;
if (!name.empty()) return name;
if (value) return value->getValue();
return "";
}
std::string MenuOption::getVirtName() const {
return virtualName.empty() ? std::string() : virtualName;
}
const std::string& MenuOption::getComment() const { return commentPtr ? *commentPtr : comment; }
bool MenuOption::isActive() const {
if (type == OPEN_SUBMENU && options.empty()) return false;
if (type == CHANGE_VALUE) {
if (!value) return false;
if (value->get_type() == "option_list" && value->ol().size() <= 1) return false;
}
return true;
}
Menu::Menu(): dimensions(), m_open(true) { clear(); }
void Menu::add(MenuOption opt) {
root_options.push_back(opt);
clear(true); // Adding resets menu stack
}
void Menu::move(int dir) {
if (dir > 0 && selection_stack.back() < menu_stack.back()->size() - 1) ++selection_stack.back();
else if (dir < 0 && selection_stack.back() > 0) --selection_stack.back();
}
void Menu::select(size_t sel) {
if (sel < menu_stack.back()->size()) selection_stack.back() = sel;
}
void Menu::action(int dir) {
switch (current().type) {
case MenuOption::OPEN_SUBMENU: {
if (current().options.empty()) break;
menu_stack.push_back(¤t().options);
selection_stack.push_back(0);
break;
}
case MenuOption::CHANGE_VALUE: {
if (current().value) {
if (current().value->getShortDesc() == config["audio/backend"].getShortDesc()) {
current().value->oldValue = current().value->getValue();
}
else if (current().value->getShortDesc() == config["graphic/stereo3d"].getShortDesc()) {
current().value->oldValue = (current().value->getValue() == _("Disabled")) ? "0" : "1";
}
if (dir > 0) ++(*(current().value));
else if (dir < 0) --(*(current().value));
}
break;
}
case MenuOption::SET_AND_CLOSE:
if (current().value) *(current().value) = current().newValue;
[[fallthrough]]; // Continuing to CLOSE_SUBMENU is intentional
case MenuOption::CLOSE_SUBMENU: {
closeSubmenu();
break;
}
case MenuOption::ACTIVATE_SCREEN: {
Game* gm = Game::getSingletonPtr();
std::string screen = current().newValue.s();
clear();
if (screen.empty()) gm->finished();
else gm->activateScreen(screen);
break;
}
case MenuOption::CALLBACK_FUNCTION: {
if (current().callback) current().callback();
break;
}
}
}
void Menu::clear(bool save_root) {
if (!save_root) root_options.clear();
menu_stack.clear();
selection_stack.clear();
menu_stack.push_back(&root_options);
selection_stack.push_back(0);
}
void Menu::closeSubmenu() {
if (menu_stack.size() > 1) {
menu_stack.pop_back();
selection_stack.pop_back();
} else close();
}
|