MenuPowers::MenuPowers(StatBlock *_stats, MenuActionBar *_action_bar) : stats(_stats) , action_bar(_action_bar) , skip_section(false) , powers_unlock(NULL) , overlay_disabled(NULL) , points_left(0) , default_background("") , tab_control(NULL) , tree_loaded(false) , prev_powers_list_size(0) , newPowerNotification(false) { closeButton = new WidgetButton("images/menus/buttons/button_x.png"); // Read powers data from config file FileParser infile; // @CLASS MenuPowers: Menu layout|Description of menus/powers.txt if (infile.open("menus/powers.txt")) { while (infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; // @ATTR label_title|label|Position of the "Powers" text. if (infile.key == "label_title") title = eatLabelInfo(infile.val); // @ATTR unspent_points|label|Position of the text that displays the amount of unused power points. else if (infile.key == "unspent_points") unspent_points = eatLabelInfo(infile.val); // @ATTR close|point|Position of the close button. else if (infile.key == "close") close_pos = toPoint(infile.val); // @ATTR tab_area|rectangle|Position and dimensions of the tree pages. else if (infile.key == "tab_area") tab_area = toRect(infile.val); else infile.error("MenuPowers: '%s' is not a valid key.", infile.key.c_str()); } infile.close(); } loadGraphics(); menu_powers = this; color_bonus = font->getColor("menu_bonus"); color_penalty = font->getColor("menu_penalty"); color_flavor = font->getColor("item_flavor"); align(); }
MenuDevConsole::MenuDevConsole() : Menu() { button_close = new WidgetButton("images/menus/buttons/button_x.png"); tablist.add(button_close); input_box = new WidgetInput("images/menus/input_console.png"); tablist.add(input_box); button_confirm = new WidgetButton(); button_confirm->label = msg->get("Execute"); tablist.add(button_confirm); // Load config settings FileParser infile; // @CLASS MenuDevConsole|Description of menus/devconsole.txt if(infile.open("menus/devconsole.txt")) { while(infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; // @ATTR close|x (integer), y (integer)|Position of the close button. if(infile.key == "close") { Point pos = toPoint(infile.val); button_close->setBasePos(pos.x, pos.y); } // @ATTR label_title|label|Position of the "Developer Console" label. else if(infile.key == "label_title") title = eatLabelInfo(infile.val); // @ATTR confirm|x (integer), y (integer)|Position of the "Execute" button. else if(infile.key == "confirm") { Point pos = toPoint(infile.val); button_confirm->setBasePos(pos.x, pos.y); } // @ATTR input|x (integer), y (integer)|Position of the command entry widget. else if(infile.key == "input") { Point pos = toPoint(infile.val); input_box->setBasePos(pos.x, pos.y); } // @ATTR history|x (integer), y (integer), w (integer), h (integer)|Position and dimensions of the command history. else if(infile.key == "history") history_area = toRect(infile.val); else infile.error("MenuDevConsole: '%s' is not a valid key.", infile.key.c_str()); } infile.close(); } log_history = new WidgetLog(history_area.w, history_area.h); log_history->setBasePos(history_area.x, history_area.y); tablist.add(log_history->getWidget()); setBackground("images/menus/dev_console.png"); color_echo = font->getColor("widget_disabled"); color_error = font->getColor("menu_penalty"); align(); input_box->inFocus = true; }
MenuLog::MenuLog() { visible = false; closeButton = new WidgetButton("images/menus/buttons/button_x.png"); // Load config settings FileParser infile; // @CLASS MenuLog|Description of menus/log.txt if(infile.open("menus/log.txt")) { while(infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; // @ATTR label_title|label|Position of the "Log" text. if(infile.key == "label_title") { title = eatLabelInfo(infile.val); } // @ATTR close|point|Position of the close button. else if(infile.key == "close") { Point pos = toPoint(infile.val); closeButton->setBasePos(pos.x, pos.y); } // @ATTR tab_area|rectangle|The position of the row of tabs, followed by the dimensions of the log text area. else if(infile.key == "tab_area") { tab_area = toRect(infile.val); } else { infile.error("MenuLog: '%s' is not a valid key.", infile.key.c_str()); } } infile.close(); } // Initialize the tab control. tabControl = new WidgetTabControl(); tablist.add(tabControl); // Store the amount of displayed log messages on each log, and the maximum. tablist_log.resize(LOG_TYPE_COUNT); for (unsigned i=0; i<LOG_TYPE_COUNT; i++) { log[i] = new WidgetLog(tab_area.w,tab_area.h); log[i]->setBasePos(tab_area.x, tab_area.y + tabControl->getTabHeight()); tablist_log[i].add(log[i]->getWidget()); tablist_log[i].setPrevTabList(&tablist); tablist_log[i].lock(); } // Define the header. tabControl->setTabTitle(LOG_TYPE_MESSAGES, msg->get("Notes")); tabControl->setTabTitle(LOG_TYPE_QUESTS, msg->get("Quests")); setBackground("images/menus/log.png"); align(); }
Subtitles::Subtitles() : current_id(-1) , visible(false) , background(NULL) , background_color(0,0,0,200) , visible_ticks(0) { FileParser infile; // @CLASS Subtitles|Description of soundfx/subtitles.txt if (infile.open("soundfx/subtitles.txt")) { while (infile.next()) { if (infile.new_section && infile.section == "subtitle") { filename.resize(filename.size()+1); text.resize(text.size()+1); } else if (infile.section == "style") { if (infile.key == "text_pos") { // @ATTR style.text_pos|label|Position and style of the subtitle text. text_pos = eatLabelInfo(infile.val); } else if (infile.key == "pos") { // @ATTR style.pos|point|Position of the subtitle text relative to alignment. label_pos = toPoint(infile.val); } else if (infile.key == "align") { // @ATTR style.align|alignment|Alignment of the subtitle text. label_alignment = parse_alignment(infile.val); } else if (infile.key == "background_color") { // @ATTR style.background_color|color, int : Color, Alpha|Color and alpha of the subtitle background rectangle. background_color = toRGBA(infile.val); } } if (filename.empty() || text.empty()) continue; if (infile.key == "id") { // @ATTR subtitle.id|filename|Filename of the sound file that will trigger this subtitle. std::locale loc; const std::collate<char>& coll = std::use_facet<std::collate<char> >(loc); const std::string realfilename = mods->locate(infile.val); unsigned long sid = coll.hash(realfilename.data(), realfilename.data()+realfilename.length()); filename.back() = sid; } else if (infile.key == "text") { // @ATTR subtitle.text|string|The subtitle text that will be displayed. text.back() = msg->get(infile.val); } } } assert(filename.size() == text.size()); }
MenuEnemy::MenuEnemy() : bar_hp(NULL) , custom_text_pos(false) , enemy(NULL) , timeout(0) { // Load config settings FileParser infile; // @CLASS MenuEnemy|Description of menus/enemy.txt if(infile.open("menus/enemy.txt")) { while(infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; infile.val = infile.val + ','; // @ATTR bar_pos|rectangle|Position and dimensions of the health bar. if(infile.key == "bar_pos") { bar_pos = toRect(infile.val); } // @ATTR text_pos|label|Position of the text displaying the enemy's name and level. else if(infile.key == "text_pos") { custom_text_pos = true; text_pos = eatLabelInfo(infile.val); } else { infile.error("MenuEnemy: '%s' is not a valid key.", infile.key.c_str()); } } infile.close(); } loadGraphics(); color_normal = font->getColor("menu_normal"); align(); }
MenuStash::MenuStash(StatBlock *_stats) : Menu() , stats(_stats) , closeButton(new WidgetButton("images/menus/buttons/button_x.png")) , color_normal(font->getColor("menu_normal")) , stock() , updated(false) { setBackground("images/menus/stash.png"); slots_cols = 8; // default if menus/stash.txt::stash_cols not set slots_rows = 8; // default if menus/stash.txt::slots_rows not set // Load config settings FileParser infile; // @CLASS MenuStash|Description of menus/stash.txt if (infile.open("menus/stash.txt")) { while(infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; // @ATTR close|x (integer), y (integer)|Position of the close button. if (infile.key == "close") { Point pos = toPoint(infile.val); closeButton->setBasePos(pos.x, pos.y); } // @ATTR slots_area|x (integer), y (integer)|Position of the top-left slot. else if (infile.key == "slots_area") { slots_area.x = popFirstInt(infile.val); slots_area.y = popFirstInt(infile.val); } // @ATTR stash_cols|integer|The number of columns for the grid of slots. else if (infile.key == "stash_cols") { slots_cols = std::max(1, toInt(infile.val)); } // @ATTR stash_rows|integer|The number of rows for the grid of slots. else if (infile.key == "stash_rows") { slots_rows = std::max(1, toInt(infile.val)); } // @ATTR label_title|label|Position of the "Stash" label. else if (infile.key == "label_title") { title = eatLabelInfo(infile.val); } // @ATTR currency|label|Position of the label displaying the amount of currency stored in the stash. else if (infile.key == "currency") { currency = eatLabelInfo(infile.val); } else { infile.error("MenuStash: '%s' is not a valid key.", infile.key.c_str()); } } infile.close(); } STASH_SLOTS = slots_cols * slots_rows; slots_area.w = slots_cols*ICON_SIZE; slots_area.h = slots_rows*ICON_SIZE; stock.init( STASH_SLOTS, slots_area, ICON_SIZE, slots_cols); for (int i = 0; i < STASH_SLOTS; i++) { tablist.add(stock.slots[i]); } align(); }
GameStateLoad::GameStateLoad() : GameState() , background(NULL) , selection(NULL) , portrait_border(NULL) , portrait(NULL) , loading_requested(false) , loading(false) , loaded(false) , delete_items(true) , selected_slot(-1) , visible_slots(0) , scroll_offset(0) , has_scroll_bar(false) , game_slot_max(4) , text_trim_boundary(0) { if (items == NULL) items = new ItemManager(); label_loading = new WidgetLabel(); // Confirmation box to confirm deleting confirm = new MenuConfirm(msg->get("Delete Save"), msg->get("Delete this save?")); button_exit = new WidgetButton(); button_exit->label = msg->get("Exit to Title"); button_new = new WidgetButton(); button_new->label = msg->get("New Game"); button_new->enabled = true; button_load = new WidgetButton(); button_load->label = msg->get("Choose a Slot"); button_load->enabled = false; button_delete = new WidgetButton(); button_delete->label = msg->get("Delete Save"); button_delete->enabled = false; scrollbar = new WidgetScrollBar(); // Set up tab list tablist = TabList(HORIZONTAL); tablist.add(button_exit); tablist.add(button_new); // Read positions from config file FileParser infile; // @CLASS GameStateLoad|Description of menus/gameload.txt if (infile.open("menus/gameload.txt")) { while (infile.next()) { // @ATTR button_new|int, int, alignment : X, Y, Alignment|Position of the "New Game" button. if (infile.key == "button_new") { int x = popFirstInt(infile.val); int y = popFirstInt(infile.val); ALIGNMENT a = parse_alignment(popFirstString(infile.val)); button_new->setBasePos(x, y, a); } // @ATTR button_load|int, int, alignment : X, Y, Alignment|Position of the "Load Game" button. else if (infile.key == "button_load") { int x = popFirstInt(infile.val); int y = popFirstInt(infile.val); ALIGNMENT a = parse_alignment(popFirstString(infile.val)); button_load->setBasePos(x, y, a); } // @ATTR button_delete|int, int, alignment : X, Y, Alignment|Position of the "Delete Save" button. else if (infile.key == "button_delete") { int x = popFirstInt(infile.val); int y = popFirstInt(infile.val); ALIGNMENT a = parse_alignment(popFirstString(infile.val)); button_delete->setBasePos(x, y, a); } // @ATTR button_exit|int, int, alignment : X, Y, Alignment|Position of the "Exit to Title" button. else if (infile.key == "button_exit") { int x = popFirstInt(infile.val); int y = popFirstInt(infile.val); ALIGNMENT a = parse_alignment(popFirstString(infile.val)); button_exit->setBasePos(x, y, a); } // @ATTR portrait|rectangle|Position and dimensions of the portrait image. else if (infile.key == "portrait") { portrait_dest = toRect(infile.val); } // @ATTR gameslot|rectangle|Position and dimensions of the first game slot. else if (infile.key == "gameslot") { gameslot_pos = toRect(infile.val); } // @ATTR name|label|The label for the hero's name. Position is relative to game slot position. else if (infile.key == "name") { name_pos = eatLabelInfo(infile.val); } // @ATTR level|label|The label for the hero's level. Position is relative to game slot position. else if (infile.key == "level") { level_pos = eatLabelInfo(infile.val); } // @ATTR class|label|The label for the hero's class. Position is relative to game slot position. else if (infile.key == "class") { class_pos = eatLabelInfo(infile.val); } // @ATTR map|label|The label for the hero's current location. Position is relative to game slot position. else if (infile.key == "map") { map_pos = eatLabelInfo(infile.val); } // @ATTR slot_number|label|The label for the save slot index. Position is relative to game slot position. else if (infile.key == "slot_number") { slot_number_pos = eatLabelInfo(infile.val); } // @ATTR loading_label|label|The label for the "Entering game world..."/"Loading saved game..." text. else if (infile.key == "loading_label") { loading_pos = eatLabelInfo(infile.val); } // @ATTR sprite|point|Position for the avatar preview image in each slot else if (infile.key == "sprite") { sprites_pos = toPoint(infile.val); } // @ATTR visible_slots|int|The maximum numbers of visible save slots. else if (infile.key == "visible_slots") { game_slot_max = toInt(infile.val); // can't have less than 1 game slot visible game_slot_max = std::max(game_slot_max, 1); } // @ATTR text_trim_boundary|int|The position of the right-side boundary where text will be shortened with an ellipsis. Position is relative to game slot position. else if (infile.key == "text_trim_boundary") { text_trim_boundary = toInt(infile.val); } else { infile.error("GameStateLoad: '%s' is not a valid key.", infile.key.c_str()); } } infile.close(); } // prevent text from overflowing on the right edge of game slots if (text_trim_boundary == 0 || text_trim_boundary > gameslot_pos.w) text_trim_boundary = gameslot_pos.w; button_new->refresh(); button_load->refresh(); button_delete->refresh(); loadGraphics(); readGameSlots(); color_normal = font->getColor("menu_normal"); refreshWidgets(); updateButtons(); // if we specified a slot to load at launch, load it now if (!LOAD_SLOT.empty()) { size_t load_slot_id = toInt(LOAD_SLOT) - 1; LOAD_SLOT.clear(); if (load_slot_id < game_slots.size()) { setSelectedSlot(static_cast<int>(load_slot_id)); loading_requested = true; } } render_device->setBackgroundColor(Color(0,0,0,0)); }
MenuVendor::MenuVendor(StatBlock *_stats) : Menu() , stats(_stats) , closeButton(new WidgetButton("images/menus/buttons/button_x.png")) , tabControl(new WidgetTabControl()) , slots_cols(1) , slots_rows(1) , activetab(VENDOR_BUY) , color_normal(font->getColor("menu_normal")) , npc(NULL) , buyback_stock() { setBackground("images/menus/vendor.png"); tabControl->setTabTitle(VENDOR_BUY, msg->get("Inventory")); tabControl->setTabTitle(VENDOR_SELL, msg->get("Buyback")); // Load config settings FileParser infile; // @CLASS MenuVendor|Description of menus/vendor.txt if(infile.open("menus/vendor.txt")) { while(infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; // @ATTR close|x (integer), y (integer)|Position of the close button. if(infile.key == "close") { Point pos = toPoint(infile.val); closeButton->setBasePos(pos.x, pos.y); } // @ATTR slots_area|x (integer), y (integer)|Position of the top-left slot. else if(infile.key == "slots_area") { slots_area.x = popFirstInt(infile.val); slots_area.y = popFirstInt(infile.val); } // @ATTR vendor_cols|integer|The number of columns in the grid of slots. else if (infile.key == "vendor_cols") { slots_cols = std::max(1, toInt(infile.val)); } // @ATTR vendor_rows|integer|The number of rows in the grid of slots. else if (infile.key == "vendor_rows") { slots_rows = std::max(1, toInt(infile.val)); } // @ATTR label_title|label|The position of the text that displays the NPC's name. else if (infile.key == "label_title") { title = eatLabelInfo(infile.val); } else { infile.error("MenuVendor: '%s' is not a valid key.", infile.key.c_str()); } } infile.close(); } VENDOR_SLOTS = slots_cols * slots_rows; slots_area.w = slots_cols*ICON_SIZE; slots_area.h = slots_rows*ICON_SIZE; stock[VENDOR_BUY].init(VENDOR_SLOTS, slots_area, ICON_SIZE, slots_cols); stock[VENDOR_SELL].init(VENDOR_SLOTS, slots_area, ICON_SIZE, slots_cols); buyback_stock.init(NPC_VENDOR_MAX_STOCK); for (unsigned i = 0; i < VENDOR_SLOTS; i++) { tablist.add(stock[VENDOR_BUY].slots[i]); } for (unsigned i = 0; i < VENDOR_SLOTS; i++) { tablist.add(stock[VENDOR_SELL].slots[i]); } align(); }
MenuInventory::MenuInventory(StatBlock *_stats) { stats = _stats; MAX_EQUIPPED = 4; MAX_CARRIED = 64; visible = false; setBackground("images/menus/inventory.png"); currency = 0; carried_cols = 4; // default to 4 if menus/inventory.txt::carried_cols not set carried_rows = 4; // default to 4 if menus/inventory.txt::carried_rows not set drag_prev_src = -1; changed_equipment = true; log_msg = ""; show_book = ""; closeButton = new WidgetButton("images/menus/buttons/button_x.png"); // Load config settings FileParser infile; // @CLASS MenuInventory|Description of menus/inventory.txt if (infile.open("menus/inventory.txt")) { while(infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; // @ATTR close|x (integer), y (integer)|Position of the close button. if(infile.key == "close") { Point pos = toPoint(infile.val); closeButton->setBasePos(pos.x, pos.y); } // @ATTR equipment_slot|x (integer), y (integer), size (integer), slot_type (string)|Position and item type of an equipment slot. else if(infile.key == "equipment_slot") { Rect area; Point pos; pos.x = area.x = popFirstInt(infile.val); pos.y = area.y = popFirstInt(infile.val); area.w = area.h = popFirstInt(infile.val); equipped_area.push_back(area); equipped_pos.push_back(pos); slot_type.push_back(popFirstString(infile.val)); } // @ATTR slot_name|string|The displayed name of the last defined equipment slot. else if(infile.key == "slot_name") slot_desc.push_back(infile.val); // @ATTR carried_area|x (integer), y (integer)|Position of the first normal inventory slot. else if(infile.key == "carried_area") { Point pos; carried_pos.x = carried_area.x = popFirstInt(infile.val); carried_pos.y = carried_area.y = popFirstInt(infile.val); } // @ATTR carried_cols|integer|The number of columns for the normal inventory. else if (infile.key == "carried_cols") carried_cols = std::max(1, toInt(infile.val)); // @ATTR carried_rows|integer|The number of rows for the normal inventory. else if (infile.key == "carried_rows") carried_rows = std::max(1, toInt(infile.val)); // @ATTR label_title|label|Position of the "Inventory" label. else if (infile.key == "label_title") title = eatLabelInfo(infile.val); // @ATTR currency|label|Position of the label that displays the total currency being carried. else if (infile.key == "currency") currency_lbl = eatLabelInfo(infile.val); // @ATTR help|x (integer), y (integer), w (integer), h (integer)|A mouse-over area that displays some help text for inventory shortcuts. else if (infile.key == "help") help_pos = toRect(infile.val); else infile.error("MenuInventory: '%s' is not a valid key.", infile.key.c_str()); } infile.close(); } MAX_EQUIPPED = equipped_area.size(); MAX_CARRIED = carried_cols * carried_rows; carried_area.w = carried_cols*ICON_SIZE; carried_area.h = carried_rows*ICON_SIZE; color_normal = font->getColor("menu_normal"); color_high = font->getColor("menu_bonus"); inventory[EQUIPMENT].init(MAX_EQUIPPED, equipped_area, slot_type); inventory[CARRIED].init(MAX_CARRIED, carried_area, ICON_SIZE, carried_cols); for (int i = 0; i < MAX_EQUIPPED; i++) { tablist.add(inventory[EQUIPMENT].slots[i]); } for (int i = 0; i < MAX_CARRIED; i++) { tablist.add(inventory[CARRIED].slots[i]); } align(); }
MenuInventory::MenuInventory(StatBlock *_stats) : stats(_stats) , MAX_EQUIPPED(4) , MAX_CARRIED(64) , carried_cols(4) , carried_rows(4) , tap_to_activate_ticks(0) , currency(0) , drag_prev_src(-1) , changed_equipment(true) , inv_ctrl(INV_CTRL_NONE) , show_book("") { visible = false; setBackground("images/menus/inventory.png"); closeButton = new WidgetButton("images/menus/buttons/button_x.png"); // Load config settings FileParser infile; // @CLASS MenuInventory|Description of menus/inventory.txt if (infile.open("menus/inventory.txt")) { while(infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; // @ATTR close|point|Position of the close button. if(infile.key == "close") { Point pos = toPoint(infile.val); closeButton->setBasePos(pos.x, pos.y); } // @ATTR equipment_slot|repeatable(int, int, string) : X, Y, Slot Type|Position and item type of an equipment slot. else if(infile.key == "equipment_slot") { Rect area; Point pos; pos.x = area.x = popFirstInt(infile.val); pos.y = area.y = popFirstInt(infile.val); area.w = area.h = ICON_SIZE; equipped_area.push_back(area); equipped_pos.push_back(pos); slot_type.push_back(popFirstString(infile.val)); } // @ATTR carried_area|point|Position of the first normal inventory slot. else if(infile.key == "carried_area") { Point pos; carried_pos.x = carried_area.x = popFirstInt(infile.val); carried_pos.y = carried_area.y = popFirstInt(infile.val); } // @ATTR carried_cols|int|The number of columns for the normal inventory. else if (infile.key == "carried_cols") carried_cols = std::max(1, toInt(infile.val)); // @ATTR carried_rows|int|The number of rows for the normal inventory. else if (infile.key == "carried_rows") carried_rows = std::max(1, toInt(infile.val)); // @ATTR label_title|label|Position of the "Inventory" label. else if (infile.key == "label_title") title = eatLabelInfo(infile.val); // @ATTR currency|label|Position of the label that displays the total currency being carried. else if (infile.key == "currency") currency_lbl = eatLabelInfo(infile.val); // @ATTR help|rectangle|A mouse-over area that displays some help text for inventory shortcuts. else if (infile.key == "help") help_pos = toRect(infile.val); else infile.error("MenuInventory: '%s' is not a valid key.", infile.key.c_str()); } infile.close(); } MAX_EQUIPPED = static_cast<int>(equipped_area.size()); MAX_CARRIED = carried_cols * carried_rows; carried_area.w = carried_cols*ICON_SIZE; carried_area.h = carried_rows*ICON_SIZE; color_normal = font->getColor("menu_normal"); color_high = font->getColor("menu_bonus"); inventory[EQUIPMENT].initFromList(MAX_EQUIPPED, equipped_area, slot_type); inventory[CARRIED].initGrid(MAX_CARRIED, carried_area, carried_cols); for (int i = 0; i < MAX_EQUIPPED; i++) { tablist.add(inventory[EQUIPMENT].slots[i]); } for (int i = 0; i < MAX_CARRIED; i++) { tablist.add(inventory[CARRIED].slots[i]); } align(); }
MenuExit::MenuExit() : Menu() { buttonExit = new WidgetButton(); buttonClose = new WidgetButton(); // widgets for game options music_volume_sl = new WidgetSlider(); sound_volume_sl = new WidgetSlider(); // Load config settings FileParser infile; // @CLASS MenuExit|Description of menus/exit.txt if(infile.open("menus/exit.txt")) { while(infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; else if (infile.key == "title") { // @ATTR title|label|Position of the "Paused" text. title = eatLabelInfo(infile.val); } else if (infile.key == "exit") { // @ATTR exit|point|Position of the "Save and Exit" button. Point p = toPoint(infile.val); buttonExit->setBasePos(p.x, p.y); } else if (infile.key == "continue") { // @ATTR continue|point|Position of the "Continue" button. Point p = toPoint(infile.val); buttonClose->setBasePos(p.x, p.y); } else if (infile.key == "music_volume") { // @ATTR music_volume|int, int, int, int : Label X, Label Y, Widget X, Widget Y|Position of the "Music Volume" slider relative to the frame. Rect r = toRect(infile.val); placeOptionWidgets(&music_volume_lb, music_volume_sl, r.x, r.y, r.w, r.h, msg->get("Music Volume")); } else if (infile.key == "sound_volume") { // @ATTR sound_volume|int, int, int, int : Label X, Label Y, Widget X, Widget Y|Position of the "Sound Volume" slider relative to the frame. Rect r = toRect(infile.val); placeOptionWidgets(&sound_volume_lb, sound_volume_sl, r.x, r.y, r.w, r.h, msg->get("Sound Volume")); } else infile.error("MenuExit: '%s' is not a valid key.", infile.key.c_str()); } infile.close(); } exitClicked = false; reload_music = false; if (SAVE_ONEXIT) buttonExit->label = msg->get("Save & Exit"); else buttonExit->label = msg->get("Exit"); buttonClose->label = msg->get("Continue"); setBackground("images/menus/pause_menu.png"); if (AUDIO) { music_volume_sl->set(0, 128, MUSIC_VOLUME); sound_volume_sl->set(0, 128, SOUND_VOLUME); } else { music_volume_sl->set(0, 128, 0); sound_volume_sl->set(0, 128, 0); } tablist.add(buttonClose); tablist.add(buttonExit); tablist.add(music_volume_sl); tablist.add(sound_volume_sl); align(); }