diff --git a/src/controller_base.cpp b/src/controller_base.cpp index 0bc03ae3a409..1f79472d3b38 100644 --- a/src/controller_base.cpp +++ b/src/controller_base.cpp @@ -288,17 +288,17 @@ void controller_base::play_slice(bool is_delay_enabled) } } -void controller_base::show_menu(const std::vector& items_arg, int xloc, int yloc, bool context_menu, display& disp) +void controller_base::show_menu(const std::vector& items_arg, int xloc, int yloc, bool context_menu, display& disp) { hotkey::command_executor * cmd_exec = get_hotkey_command_executor(); if (!cmd_exec) { return; } - std::vector items = items_arg; - std::vector::iterator i = items.begin(); + std::vector items = items_arg; + std::vector::iterator i = items.begin(); while(i != items.end()) { - const hotkey::hotkey_command& command = hotkey::get_hotkey_command(*i); + const hotkey::hotkey_command& command = hotkey::get_hotkey_command((*i)["id"]); if(!cmd_exec->can_execute_command(command) || (context_menu && !in_context_menu(command.id))) { i = items.erase(i); diff --git a/src/controller_base.hpp b/src/controller_base.hpp index c859d13e90c6..33aaf3909592 100644 --- a/src/controller_base.hpp +++ b/src/controller_base.hpp @@ -139,7 +139,7 @@ class controller_base : public video2::draw_layering */ virtual void process_keyup_event(const SDL_Event& event); - virtual void show_menu(const std::vector& items_arg, int xloc, int yloc, bool context_menu, display& disp); + virtual void show_menu(const std::vector& items_arg, int xloc, int yloc, bool context_menu, display& disp); virtual void execute_action(const std::vector& items_arg, int xloc, int yloc, bool context_menu); virtual bool in_context_menu(hotkey::HOTKEY_COMMAND command) const; diff --git a/src/display.cpp b/src/display.cpp index 47c7f7fa2680..0770e13cb1b7 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -1722,8 +1722,9 @@ void display::enable_menu(const std::string& item, bool enable) for(std::vector::const_iterator menu = theme_.menus().begin(); menu != theme_.menus().end(); ++menu) { - std::vector::const_iterator hasitem = - std::find(menu->items().begin(), menu->items().end(), item); + const auto hasitem = std::find_if(menu->items().begin(), menu->items().end(), + [&item](const config& c) { return c["id"].str() == item; } + ); if(hasitem != menu->items().end()) { const size_t index = menu - theme_.menus().begin(); diff --git a/src/editor/controller/editor_controller.cpp b/src/editor/controller/editor_controller.cpp index 3c9217e7f133..ec975ee10544 100644 --- a/src/editor/controller/editor_controller.cpp +++ b/src/editor/controller/editor_controller.cpp @@ -39,6 +39,7 @@ #include "resources.hpp" #include "reports.hpp" +#include "config_assign.hpp" #include "desktop/clipboard.hpp" #include "floating_label.hpp" #include "game_board.hpp" @@ -655,8 +656,8 @@ bool editor_controller::execute_command(const hotkey::hotkey_command& cmd, int i //TODO mark the map as changed sound::play_music_once(music_tracks_[index].id()); context_manager_->get_map_context().add_to_playlist(music_tracks_[index]); - std::vector items; - items.push_back("editor-playlist"); + std::vector items; + items.emplace_back(config_of("id", "editor-playlist")); std::shared_ptr b = gui_->find_menu_button("menu-playlist"); show_menu(items, b->location().x +1, b->location().y + b->height() +1, false, *gui_); return true; @@ -1005,7 +1006,7 @@ void editor_controller::show_help() help::show_help(gui_->video(), "..editor"); } -void editor_controller::show_menu(const std::vector& items_arg, int xloc, int yloc, bool context_menu, display& disp) +void editor_controller::show_menu(const std::vector& items_arg, int xloc, int yloc, bool context_menu, display& disp) { if (context_menu) { if (!context_manager_->get_map().on_board_with_border(gui().hex_clicked_on(xloc, yloc))) { @@ -1013,79 +1014,78 @@ void editor_controller::show_menu(const std::vector& items_arg, int } } - std::vector items; - std::vector::const_iterator i = items_arg.begin(); + std::vector items; + std::vector::const_iterator i = items_arg.begin(); while(i != items_arg.end()) { - - const hotkey::hotkey_command& command = hotkey::get_hotkey_command(*i); + const hotkey::hotkey_command& command = hotkey::get_hotkey_command((*i)["id"]); if ( ( can_execute_command(command) && (!context_menu || in_context_menu(command.id)) ) || command.id == hotkey::HOTKEY_NULL) { - items.push_back(*i); + items.emplace_back(config_of("id", (*i)["id"])); } ++i; } - if (!items.empty() && items.front() == "EDITOR-LOAD-MRU-PLACEHOLDER") { + if (!items.empty() && items.front()["id"] == "EDITOR-LOAD-MRU-PLACEHOLDER") { active_menu_ = editor::LOAD_MRU; context_manager_->expand_load_mru_menu(items); } - if (!items.empty() && items.front() == "editor-switch-map") { + if (!items.empty() && items.front()["id"] == "editor-switch-map") { active_menu_ = editor::MAP; context_manager_->expand_open_maps_menu(items); } - if (!items.empty() && items.front() == "editor-palette-groups") { + if (!items.empty() && items.front()["id"] == "editor-palette-groups") { active_menu_ = editor::PALETTE; toolkit_->get_palette_manager()->active_palette().expand_palette_groups_menu(items); } - if (!items.empty() && items.front() == "editor-switch-side") { + if (!items.empty() && items.front()["id"] == "editor-switch-side") { active_menu_ = editor::SIDE; context_manager_->expand_sides_menu(items); } - if (!items.empty() && items.front() == "editor-switch-area") { + if (!items.empty() && items.front()["id"] == "editor-switch-area") { active_menu_ = editor::AREA; context_manager_->expand_areas_menu(items); } - if (!items.empty() && items.front() == "editor-switch-time") { + if (!items.empty() && items.front()["id"] == "editor-switch-time") { active_menu_ = editor::TIME; context_manager_->expand_time_menu(items); } - if (!items.empty() && items.front() == "editor-assign-local-time") { + if (!items.empty() && items.front()["id"] == "editor-assign-local-time") { active_menu_ = editor::LOCAL_TIME; context_manager_->expand_local_time_menu(items); } - if (!items.empty() && items.front() == "menu-unit-facings") { + if (!items.empty() && items.front()["id"] == "menu-unit-facings") { active_menu_ = editor::UNIT_FACING; items.erase(items.begin()); for (int dir = 0; dir != map_location::NDIRECTIONS; dir++) - items.push_back(map_location::write_translated_direction(map_location::DIRECTION(dir))); + items.emplace_back(config_of("label", map_location::write_translated_direction(map_location::DIRECTION(dir)))); } - if (!items.empty() && items.front() == "editor-playlist") { + if (!items.empty() && items.front()["id"] == "editor-playlist") { active_menu_ = editor::MUSIC; items.erase(items.begin()); for (const sound::music_track& track : music_tracks_) { - items.push_back(track.title().empty() ? track.id() : track.title()); + items.emplace_back(config_of("label", track.title().empty() ? track.id() : track.title())); } } - if (!items.empty() && items.front() == "editor-assign-schedule") { + if (!items.empty() && items.front()["id"] == "editor-assign-schedule") { active_menu_ = editor::SCHEDULE; items.erase(items.begin()); for (tods_map::iterator iter = tods_.begin(); iter != tods_.end(); ++iter) { - items.push_back(iter->second.first); + items.emplace_back(config_of("label", iter->second.first)); } } - if (!items.empty() && items.front() == "editor-assign-local-schedule") { + if (!items.empty() && items.front()["id"] == "editor-assign-local-schedule") { active_menu_ = editor::LOCAL_SCHEDULE; items.erase(items.begin()); for (tods_map::iterator iter = tods_.begin(); iter != tods_.end(); ++iter) { - items.push_back(iter->second.first); + items.emplace_back(config_of("label", iter->second.first)); } } diff --git a/src/editor/controller/editor_controller.hpp b/src/editor/controller/editor_controller.hpp index 96d8bb9c6482..92ec3f965d7e 100644 --- a/src/editor/controller/editor_controller.hpp +++ b/src/editor/controller/editor_controller.hpp @@ -112,7 +112,7 @@ class editor_controller : public controller_base, bool execute_command(const hotkey::hotkey_command& command, int index = -1, bool press=true) override; /** controller_base override */ - void show_menu(const std::vector& items_arg, int xloc, int yloc, bool context_menu, display& disp) override; + void show_menu(const std::vector& items_arg, int xloc, int yloc, bool context_menu, display& disp) override; void show_help() override; void status_table() override; diff --git a/src/editor/map/context_manager.cpp b/src/editor/map/context_manager.cpp index 157b3d815e31..6bd4e2937611 100644 --- a/src/editor/map/context_manager.cpp +++ b/src/editor/map/context_manager.cpp @@ -16,6 +16,7 @@ #include "resources.hpp" #include "team.hpp" +#include "config_assign.hpp" #include "display.hpp" #include "editor/map/context_manager.hpp" #include "editor/map/map_context.hpp" @@ -44,8 +45,6 @@ #include "terrain/translation.hpp" -#include "wml_separators.hpp" - #include namespace editor { @@ -294,15 +293,15 @@ void context_manager::new_scenario_dialog() } } -void context_manager::expand_open_maps_menu(std::vector& items) +void context_manager::expand_open_maps_menu(std::vector& items) { for(unsigned int i = 0; i < items.size(); ++i) { - if(items[i] != "editor-switch-map") { + if(items[i]["id"] != "editor-switch-map") { continue; } items.erase(items.begin() + i); - std::vector contexts; + std::vector contexts; for(size_t mci = 0; mci < map_contexts_.size(); ++mci) { std::string filename = map_contexts_[mci]->get_filename(); bool changed = map_contexts_[mci]->modified(); @@ -319,26 +318,26 @@ void context_manager::expand_open_maps_menu(std::vector& items) if(map_contexts_[mci]->is_embedded()) { label += " (E)"; } - contexts.push_back(label); + contexts.emplace_back(config_of("label", label)); } items.insert(items.begin() + i, contexts.begin(), contexts.end()); break; } } -void context_manager::expand_load_mru_menu(std::vector& items) +void context_manager::expand_load_mru_menu(std::vector& items) { std::vector mru = preferences::editor::recent_files(); for(unsigned int i = 0; i < items.size(); ++i) { - if(items[i] != "EDITOR-LOAD-MRU-PLACEHOLDER") { + if(items[i]["id"] != "EDITOR-LOAD-MRU-PLACEHOLDER") { continue; } items.erase(items.begin() + i); if(mru.empty()) { - items.insert(items.begin() + i, _("No Recent Files")); + items.insert(items.begin() + i, config_of("label", _("No Recent Files"))); continue; } @@ -349,13 +348,18 @@ void context_manager::expand_load_mru_menu(std::vector& items) path = filesystem::base_name(path); } - items.insert(items.begin() + i, mru.begin(), mru.end()); + std::vector temp; + std::transform(mru.begin(), mru.end(), std::back_inserter(temp), [](const std::string& str) { + return config_of("label", str); + }); + + items.insert(items.begin() + i, temp.begin(), temp.end()); break; } } -void context_manager::expand_areas_menu(std::vector& items) +void context_manager::expand_areas_menu(std::vector& items) { tod_manager* tod = get_map_context().get_time_manager(); if(!tod) { @@ -363,12 +367,12 @@ void context_manager::expand_areas_menu(std::vector& items) } for(unsigned int i = 0; i < items.size(); ++i) { - if(items[i] != "editor-switch-area") { + if(items[i]["id"] != "editor-switch-area") { continue; } items.erase(items.begin() + i); - std::vector area_entries; + std::vector area_entries; std::vector area_ids = tod->get_area_ids(); @@ -384,7 +388,7 @@ void context_manager::expand_areas_menu(std::vector& items) label << " [*]"; } - area_entries.push_back(label.str()); + area_entries.emplace_back(config_of("label", label.str())); } items.insert(items.begin() + i, area_entries.begin(), area_entries.end()); @@ -392,15 +396,15 @@ void context_manager::expand_areas_menu(std::vector& items) } } -void context_manager::expand_sides_menu(std::vector& items) +void context_manager::expand_sides_menu(std::vector& items) { for(unsigned int i = 0; i < items.size(); ++i) { - if(items[i] != "editor-switch-side") { + if(items[i]["id"] != "editor-switch-side") { continue; } items.erase(items.begin() + i); - std::vector contexts; + std::vector contexts; for(size_t mci = 0; mci < get_map_context().get_teams().size(); ++mci) { @@ -409,7 +413,7 @@ void context_manager::expand_sides_menu(std::vector& items) std::stringstream label; label << "[" << mci+1 << "] "; label << (teamname.empty() ? _("(New Side)") : teamname); - contexts.push_back(label.str()); + contexts.emplace_back(config_of("label", label.str())); } items.insert(items.begin() + i, contexts.begin(), contexts.end()); @@ -417,27 +421,25 @@ void context_manager::expand_sides_menu(std::vector& items) } } -void context_manager::expand_time_menu(std::vector& items) +void context_manager::expand_time_menu(std::vector& items) { for(unsigned int i = 0; i < items.size(); ++i) { - if(items[i] != "editor-switch-time") { + if(items[i]["id"] != "editor-switch-time") { continue; } items.erase(items.begin() + i); - std::vector times; + std::vector times; tod_manager* tod_m = get_map_context().get_time_manager(); assert(tod_m != nullptr); for(const time_of_day& time : tod_m->times()) { - - std::stringstream label; - if(!time.image.empty()) - label << IMAGE_PREFIX << time.image << IMG_TEXT_SEPARATOR; - label << time.name; - times.push_back(label.str()); + times.emplace_back(config_of + ("details", time.name) // Use 'details' field here since the image will take the first column + ("image", time.image) + ); } items.insert(items.begin() + i, times.begin(), times.end()); @@ -445,25 +447,23 @@ void context_manager::expand_time_menu(std::vector& items) } } -void context_manager::expand_local_time_menu(std::vector& items) +void context_manager::expand_local_time_menu(std::vector& items) { for(unsigned int i = 0; i < items.size(); ++i) { - if(items[i] != "editor-assign-local-time") { + if(items[i]["id"] != "editor-assign-local-time") { continue; } items.erase(items.begin() + i); - std::vector times; + std::vector times; tod_manager* tod_m = get_map_context().get_time_manager(); for(const time_of_day& time : tod_m->times(get_map_context().get_active_area())) { - - std::stringstream label; - if(!time.image.empty()) - label << IMAGE_PREFIX << time.image << IMG_TEXT_SEPARATOR; - label << time.name; - times.push_back(label.str()); + times.emplace_back(config_of + ("details", time.name) // Use 'details' field here since the image will take the first column + ("image", time.image) + ); } items.insert(items.begin() + i, times.begin(), times.end()); diff --git a/src/editor/map/context_manager.hpp b/src/editor/map/context_manager.hpp index 2a9d256bc150..c9570be0e92d 100644 --- a/src/editor/map/context_manager.hpp +++ b/src/editor/map/context_manager.hpp @@ -105,22 +105,22 @@ class context_manager void rename_area_dialog(); /** Menu expanding for open maps list */ - void expand_open_maps_menu(std::vector& items); + void expand_open_maps_menu(std::vector& items); /** Menu expanding for most recent loaded list */ - void expand_load_mru_menu(std::vector& items); + void expand_load_mru_menu(std::vector& items); /** Menu expanding for the map's player sides */ - void expand_sides_menu(std::vector& items); + void expand_sides_menu(std::vector& items); /** Menu expanding for the map's defined areas */ - void expand_areas_menu(std::vector& items); + void expand_areas_menu(std::vector& items); /** Menu expanding for the map's defined areas */ - void expand_time_menu(std::vector& items); + void expand_time_menu(std::vector& items); /** Menu expanding for the map's defined areas */ - void expand_local_time_menu(std::vector& items); + void expand_local_time_menu(std::vector& items); /** Display a load map dialog and process user input. */ void load_map_dialog(bool force_same_context = false); diff --git a/src/editor/palette/common_palette.hpp b/src/editor/palette/common_palette.hpp index c31e96e026d8..d175d92c3055 100644 --- a/src/editor/palette/common_palette.hpp +++ b/src/editor/palette/common_palette.hpp @@ -75,7 +75,7 @@ class common_palette : public gui::widget { virtual const std::vector& get_groups() const = 0; /** Menu expanding for palette group list */ - virtual void expand_palette_groups_menu(std::vector& items) = 0; + virtual void expand_palette_groups_menu(std::vector& items) = 0; virtual void expand_palette_groups_menu(std::vector< std::pair< std::string, std::string> >& items) = 0; //item diff --git a/src/editor/palette/editor_palettes.cpp b/src/editor/palette/editor_palettes.cpp index 4f7f553e43ba..4d1ecd433dea 100644 --- a/src/editor/palette/editor_palettes.cpp +++ b/src/editor/palette/editor_palettes.cpp @@ -16,6 +16,7 @@ #include "editor/palette/editor_palettes.hpp" +#include "config_assign.hpp" #include "gettext.hpp" #include "font/text_formatting.hpp" #include "tooltips.hpp" @@ -25,8 +26,6 @@ #include "editor/toolkit/editor_toolkit.hpp" -#include "wml_separators.hpp" - namespace editor { template @@ -43,13 +42,13 @@ template sdl_handler_vector editor_palette::handler_members(); template sdl_handler_vector editor_palette::handler_members(); template -void editor_palette::expand_palette_groups_menu(std::vector& items) +void editor_palette::expand_palette_groups_menu(std::vector& items) { for (unsigned int i = 0; i < items.size(); ++i) { - if (items[i] == "editor-palette-groups") { + if (items[i]["id"] == "editor-palette-groups") { items.erase(items.begin() + i); - std::vector groups; + std::vector groups; const std::vector& item_groups = get_groups(); for (size_t mci = 0; mci < item_groups.size(); ++mci) { @@ -57,32 +56,34 @@ void editor_palette::expand_palette_groups_menu(std::vector& if (groupname.empty()) { groupname = _("(Unknown Group)"); } - std::stringstream str; - str << IMAGE_PREFIX << item_groups[mci].icon; + std::stringstream i_ss; + i_ss << item_groups[mci].icon; if (mci == active_group_index()) { - if (filesystem::file_exists(str.str() + "_30-pressed.png" ) ) { - str << "_30-pressed.png"; + if (filesystem::file_exists(i_ss.str() + "_30-pressed.png" ) ) { + i_ss << "_30-pressed.png"; } else { - str << "_30.png~CS(70,70,0)"; + i_ss << "_30.png~CS(70,70,0)"; } } else { - str << "_30.png"; + i_ss << "_30.png"; } - str << COLUMN_SEPARATOR << groupname; - groups.push_back(str.str()); - + groups.emplace_back(config_of + ("label", groupname) + ("icon", i_ss.str()) + ); } + items.insert(items.begin() + i, groups.begin(), groups.end()); break; } } } -template void editor_palette::expand_palette_groups_menu(std::vector& items); -template void editor_palette::expand_palette_groups_menu(std::vector& items); -template void editor_palette::expand_palette_groups_menu(std::vector& items); +template void editor_palette::expand_palette_groups_menu(std::vector& items); +template void editor_palette::expand_palette_groups_menu(std::vector& items); +template void editor_palette::expand_palette_groups_menu(std::vector& items); template bool editor_palette::scroll_up() diff --git a/src/editor/palette/editor_palettes.hpp b/src/editor/palette/editor_palettes.hpp index 1c627a5164d4..3b4aa695a1bc 100644 --- a/src/editor/palette/editor_palettes.hpp +++ b/src/editor/palette/editor_palettes.hpp @@ -64,7 +64,7 @@ class editor_palette : public tristate_palette { /** Menu expanding for palette group list */ void expand_palette_groups_menu(std::vector< std::pair >& items) override; - void expand_palette_groups_menu(std::vector& items) override; + void expand_palette_groups_menu(std::vector& items) override; void set_group(size_t index) override; // int active_group(); diff --git a/src/editor/palette/empty_palette.hpp b/src/editor/palette/empty_palette.hpp index 0e72537dae88..03b6fa155f70 100644 --- a/src/editor/palette/empty_palette.hpp +++ b/src/editor/palette/empty_palette.hpp @@ -73,7 +73,7 @@ class empty_palette : public common_palette { /** Menu expanding for palette group list */ virtual void expand_palette_groups_menu(std::vector< std::pair< std::string, std::string> >& /*items*/) override {} - virtual void expand_palette_groups_menu(std::vector< std::string> & /*items*/) override {} + virtual void expand_palette_groups_menu(std::vector< config> & /*items*/) override {} //item virtual int num_items() override {return 0;} diff --git a/src/editor/palette/location_palette.hpp b/src/editor/palette/location_palette.hpp index 2c2662882118..8edd9387ff97 100644 --- a/src/editor/palette/location_palette.hpp +++ b/src/editor/palette/location_palette.hpp @@ -43,7 +43,7 @@ class location_palette : public common_palette { /** Menu expanding for palette group list */ void expand_palette_groups_menu(std::vector< std::pair >&) override {} - void expand_palette_groups_menu(std::vector&) override {} + void expand_palette_groups_menu(std::vector&) override {} virtual void set_group(size_t /*index*/) override {} virtual void next_group() override {} diff --git a/src/editor/toolkit/editor_toolkit.cpp b/src/editor/toolkit/editor_toolkit.cpp index 98b0ffcd278e..831143aae8d0 100644 --- a/src/editor/toolkit/editor_toolkit.cpp +++ b/src/editor/toolkit/editor_toolkit.cpp @@ -86,7 +86,7 @@ void editor_toolkit::init_mouse_actions(context_manager& cmanager) for (const theme::menu& menu : gui_.get_theme().menus()) { if (menu.items().size() == 1) { - hotkey::HOTKEY_COMMAND hk = hotkey::get_id(menu.items().front()); + hotkey::HOTKEY_COMMAND hk = hotkey::get_id(menu.items().front()["id"]); mouse_action_map::iterator i = mouse_actions_.find(hk); if (i != mouse_actions_.end()) { i->second->set_toolbar_button(&menu); diff --git a/src/game_events/wmi_container.cpp b/src/game_events/wmi_container.cpp index 95f67e75918b..b91fde21bd74 100644 --- a/src/game_events/wmi_container.cpp +++ b/src/game_events/wmi_container.cpp @@ -24,6 +24,7 @@ #include "play_controller.hpp" #include "config.hpp" +#include "config_assign.hpp" #include "game_data.hpp" #include "log.hpp" #include "map/location.hpp" @@ -106,7 +107,7 @@ bool wmi_container::fire_item(const std::string & id, const map_location & hex, */ void wmi_container::get_items(const map_location& hex, std::vector>& items, - std::vector& descriptions, + std::vector& descriptions, filter_context& fc, game_data& gamedata, unit_map& units) const { if ( empty() ) { @@ -127,7 +128,7 @@ void wmi_container::get_items(const map_location& hex, { // Include this item. items.push_back(item); - descriptions.push_back(item->menu_text()); + descriptions.emplace_back(config_of("id", item->menu_text())); } } return; diff --git a/src/game_events/wmi_container.hpp b/src/game_events/wmi_container.hpp index 33599b2dde61..f44e69da752f 100644 --- a/src/game_events/wmi_container.hpp +++ b/src/game_events/wmi_container.hpp @@ -80,7 +80,7 @@ class wmi_container{ /// Returns the menu items that can be shown for the given location. void get_items(const map_location& hex, std::vector>& items, - std::vector& descriptions, + std::vector& descriptions, filter_context& fc, game_data& gamedata, unit_map& units) const; /// Initializes the implicit event handlers for inlined [command]s. void init_handlers() const; diff --git a/src/hotkey/command_executor.cpp b/src/hotkey/command_executor.cpp index 03e3b7c39189..b168c99ec242 100644 --- a/src/hotkey/command_executor.cpp +++ b/src/hotkey/command_executor.cpp @@ -358,16 +358,17 @@ bool command_executor::execute_command(const hotkey_command& cmd, int /*index*/ } -void command_executor::show_menu(const std::vector& items_arg, int xloc, int yloc, bool /*context_menu*/, display& gui) +void command_executor::show_menu(const std::vector& items_arg, int xloc, int yloc, bool /*context_menu*/, display& gui) { - std::vector items = items_arg; + std::vector items = items_arg; if (items.empty()) return; - std::vector menu = get_menu_images(gui, items); + get_menu_images(gui, items); + int res = -1; { SDL_Rect pos = {xloc, yloc, 1, 1}; - gui2::dialogs::drop_down_menu mmenu(pos, menu, -1, false, false); // TODO: last value should be variable + gui2::dialogs::drop_down_menu mmenu(pos, items, -1, false, false); // TODO: last value should be variable mmenu.show(gui.video()); if(mmenu.get_retval() == gui2::window::OK) { res = mmenu.selected_item(); @@ -375,13 +376,13 @@ void command_executor::show_menu(const std::vector& items_arg, int } // This will kill the dialog. if (res < 0 || size_t(res) >= items.size()) return; - const theme::menu* submenu = gui.get_theme().get_menu_item(items[res]); + const theme::menu* submenu = gui.get_theme().get_menu_item(items[res]["id"]); if (submenu) { int y,x; SDL_GetMouseState(&x,&y); this->show_menu(submenu->items(), x, y, submenu->is_context(), gui); } else { - const hotkey::hotkey_command& cmd = hotkey::get_hotkey_command(items[res]); + const hotkey::hotkey_command& cmd = hotkey::get_hotkey_command(items[res]["id"]); hotkey::execute_command(cmd,this,res); set_button_state(); } @@ -448,60 +449,43 @@ std::string command_executor::get_menu_image(display& disp, const std::string& c } } -std::vector command_executor::get_menu_images(display& disp, const std::vector& items) { - std::vector result; - +void command_executor::get_menu_images(display& disp, std::vector& items) +{ for(size_t i = 0; i < items.size(); ++i) { - const std::string& item = items[i]; - const hotkey::HOTKEY_COMMAND hk = hotkey::get_id(item); - result.emplace_back(); + config& item = items[i]; + + const std::string& item_id = item["id"]; + const hotkey::HOTKEY_COMMAND hk = hotkey::get_id(item_id); //see if this menu item has an associated image - std::string img(get_menu_image(disp, item, i)); + std::string img(get_menu_image(disp, item_id, i)); if (img.empty() == false) { - result.back()["icon"] = img; + item["icon"] = img; } - const theme::menu* menu = disp.get_theme().get_menu_item(item); + const theme::menu* menu = disp.get_theme().get_menu_item(item_id); if (hk == hotkey::HOTKEY_NULL) { - if (menu) - result.back()["label"] = menu->title(); - else { - std::string label(item.begin(), item.begin() + item.find_last_not_of(' ') + 1); - - // TODO: To away with the fugly markup, both '=' and 0x01 - size_t separator_pos = label.find_first_of('='); - if(separator_pos != std::string::npos) - result.back()["label"] = label.substr(separator_pos + 1); - else { - separator_pos = label.find_first_of(1); - if(separator_pos != std::string::npos) { - result.back()["details"] = label.substr(separator_pos + 1); - result.back()["image"] = label.substr(1, separator_pos - 1); - } else { - result.back()["label"] = label; - } - } + if (menu) { + item["label"] = menu->title(); } } else { - - if (menu) - result.back()["label"] = menu->title(); - else { - std::string desc = hotkey::get_description(item); + if (menu) { + item["label"] = menu->title(); + } else { + std::string desc = hotkey::get_description(item_id); if (hk == HOTKEY_ENDTURN) { const theme::action *b = disp.get_theme().get_action_item("button-endturn"); if (b) { desc = b->title(); } } - result.back()["label"] = desc; - result.back()["details"] = hotkey::get_names(item); + item["label"] = desc; + item["details"] = hotkey::get_names(item_id); } } } - return result; } + basic_handler::basic_handler(command_executor* exec) : exec_(exec) {} void basic_handler::handle_event(const SDL_Event& event) @@ -658,9 +642,9 @@ void command_executor_default::set_button_state() std::shared_ptr button = disp.find_menu_button(menu.get_id()); if (!button) continue; bool enabled = false; - for (const std::string& command : menu.items()) { + for (const auto& command : menu.items()) { - const hotkey::hotkey_command& command_obj = hotkey::get_hotkey_command(command); + const hotkey::hotkey_command& command_obj = hotkey::get_hotkey_command(command["id"]); bool can_execute = can_execute_command(command_obj); if (can_execute) { enabled = true; diff --git a/src/hotkey/command_executor.hpp b/src/hotkey/command_executor.hpp index e5b32ee167c9..6d78e45316e0 100644 --- a/src/hotkey/command_executor.hpp +++ b/src/hotkey/command_executor.hpp @@ -130,9 +130,9 @@ class command_executor // Returns the appropriate menu image. Checkable items will get a checked/unchecked image. std::string get_menu_image(display& disp, const std::string& command, int index=-1) const; // Returns a vector of images for a given menu. - std::vector get_menu_images(display &, const std::vector& items_arg); + void get_menu_images(display &, std::vector& items); - virtual void show_menu(const std::vector& items_arg, int xloc, int yloc, bool context_menu, display& gui); + virtual void show_menu(const std::vector& items_arg, int xloc, int yloc, bool context_menu, display& gui); void execute_action(const std::vector& items_arg, int xloc, int yloc, bool context_menu, display& gui); virtual bool can_execute_command(const hotkey_command& command, int index=-1) const = 0; diff --git a/src/hotkey/hotkey_handler.cpp b/src/hotkey/hotkey_handler.cpp index 0095d48126a0..d1bfeae5ed21 100644 --- a/src/hotkey/hotkey_handler.cpp +++ b/src/hotkey/hotkey_handler.cpp @@ -15,6 +15,7 @@ #include "hotkey/hotkey_handler.hpp" #include "actions/create.hpp" +#include "config_assign.hpp" #include "font/standard_colors.hpp" #include "formula/string_utils.hpp" #include "game_display.hpp" @@ -361,9 +362,9 @@ bool play_controller::hotkey_handler::can_execute_command(const hotkey::hotkey_c } -static void trim_items(std::vector& newitems) { +static void trim_items(std::vector& newitems) { if (newitems.size() > 5) { - std::vector subitems; + std::vector subitems; subitems.push_back(newitems[0]); subitems.push_back(newitems[1]); subitems.push_back(newitems[newitems.size() / 3]); @@ -373,31 +374,31 @@ static void trim_items(std::vector& newitems) { } } -void play_controller::hotkey_handler::expand_autosaves(std::vector& items) +void play_controller::hotkey_handler::expand_autosaves(std::vector& items) { const compression::format comp_format = preferences::save_compression_format(); savenames_.clear(); for (unsigned int i = 0; i < items.size(); ++i) { - if (items[i] == "AUTOSAVES") { + if (items[i]["id"] == "AUTOSAVES") { items.erase(items.begin() + i); - std::vector newitems; - std::vector newsaves; + std::vector newitems; + std::vector newsaves; for (unsigned int turn = play_controller_.turn(); turn != 0; turn--) { std::string name = saved_game_.classification().label + "-" + _("Auto-Save") + std::to_string(turn); if (savegame::save_game_exists(name, comp_format)) { - newsaves.push_back( - name + compression::format_extension(comp_format)); - newitems.push_back(_("Back to Turn ") + std::to_string(turn)); + newsaves.emplace_back(config_of("label", + name + compression::format_extension(comp_format))); + newitems.emplace_back(config_of("label", _("Back to Turn ") + std::to_string(turn))); } } const std::string& start_name = saved_game_.classification().label; if(savegame::save_game_exists(start_name, comp_format)) { - newsaves.push_back( - start_name + compression::format_extension(comp_format)); - newitems.push_back(_("Back to Start")); + newsaves.emplace_back(config_of("label", + start_name + compression::format_extension(comp_format))); + newitems.emplace_back(config_of("label", _("Back to Start"))); } // Make sure list doesn't get too long: keep top two, @@ -405,20 +406,25 @@ void play_controller::hotkey_handler::expand_autosaves(std::vector& trim_items(newitems); trim_items(newsaves); + std::vector temp; + std::transform(newsaves.begin(), newsaves.end(), std::back_inserter(temp), [](const config& c) { + return c["label"].str(); + }); + items.insert(items.begin()+i, newitems.begin(), newitems.end()); - savenames_.insert(savenames_.end(), newsaves.begin(), newsaves.end()); + savenames_.insert(savenames_.end(), temp.begin(), temp.end()); break; } savenames_.push_back(""); } } -void play_controller::hotkey_handler::expand_wml_commands(std::vector& items) +void play_controller::hotkey_handler::expand_wml_commands(std::vector& items) { wml_commands_.clear(); for (unsigned int i = 0; i < items.size(); ++i) { - if (items[i] == "wml") { - std::vector newitems; + if (items[i]["id"] == "wml") { + std::vector newitems; // Replace this placeholder entry with available menu items. items.erase(items.begin() + i); @@ -434,7 +440,7 @@ void play_controller::hotkey_handler::expand_wml_commands(std::vector& items_arg, int xloc, int yloc, bool context_menu, display& disp) +void play_controller::hotkey_handler::show_menu(const std::vector& items_arg, int xloc, int yloc, bool context_menu, display& disp) { if (context_menu) { @@ -442,19 +448,19 @@ void play_controller::hotkey_handler::show_menu(const std::vector& last_context_menu_y_ = yloc; } - std::vector items = items_arg; + std::vector items = items_arg; const hotkey::hotkey_command* cmd; - std::vector::iterator i = items.begin(); + std::vector::iterator i = items.begin(); while(i != items.end()) { - if (*i == "AUTOSAVES") { + if ((*i)["id"] == "AUTOSAVES") { // Autosave visibility is similar to LOAD_GAME hotkey ++i; continue; //cmd = &hotkey::hotkey_command::get_command_by_command(hotkey::HOTKEY_LOAD_GAME); } else { - cmd = &hotkey::get_hotkey_command(*i); + cmd = &hotkey::get_hotkey_command((*i)["id"]); } // Remove commands that can't be executed or don't belong in this type of menu - if(*i != "wml" && (!can_execute_command(*cmd) || (context_menu && !in_context_menu(cmd->id)))) { + if((*i)["id"] != "wml" && (!can_execute_command(*cmd) || (context_menu && !in_context_menu(cmd->id)))) { i = items.erase(i); continue; } diff --git a/src/hotkey/hotkey_handler.hpp b/src/hotkey/hotkey_handler.hpp index 26061ce91948..cac592e2d173 100644 --- a/src/hotkey/hotkey_handler.hpp +++ b/src/hotkey/hotkey_handler.hpp @@ -57,14 +57,14 @@ class play_controller::hotkey_handler : public hotkey::command_executor_default typedef std::shared_ptr const_item_ptr; // Expand AUTOSAVES in the menu items, setting the real savenames. - void expand_autosaves(std::vector& items); + void expand_autosaves(std::vector& items); std::vector savenames_; /** * Replaces "wml" in @a items with all active WML menu items for the current field. */ - void expand_wml_commands(std::vector& items); + void expand_wml_commands(std::vector& items); std::vector wml_commands_; int last_context_menu_x_; int last_context_menu_y_; @@ -125,7 +125,7 @@ class play_controller::hotkey_handler : public hotkey::command_executor_default /** Check if a command can be executed. */ virtual bool can_execute_command(const hotkey::hotkey_command& command, int index=-1) const override; virtual bool execute_command(const hotkey::hotkey_command& command, int index=-1, bool press=true) override; - void show_menu(const std::vector& items_arg, int xloc, int yloc, bool context_menu, display& disp) override; + void show_menu(const std::vector& items_arg, int xloc, int yloc, bool context_menu, display& disp) override; /** * Determines whether the command should be in the context menu or not. diff --git a/src/theme.cpp b/src/theme.cpp index 6a3fc3b2c3aa..8fbae38631e1 100644 --- a/src/theme.cpp +++ b/src/theme.cpp @@ -14,6 +14,7 @@ /** @file */ +#include "config_assign.hpp" #include "font/sdl_ttf.hpp" #include "gettext.hpp" #include "hotkey/hotkey_command.hpp" @@ -555,14 +556,18 @@ theme::menu::menu(const config &cfg): context_(cfg["is_context_menu"].to_bool(false)), title_(cfg["title"].str() + cfg["title_literal"].str()), tooltip_(cfg["tooltip"]), image_(cfg["image"]), overlay_(cfg["overlay"]), - items_(utils::split(cfg["items"])) + items_() { + for(const auto& item : utils::split(cfg["items"])) { + items_.emplace_back(config_of("id", item)); + } + if (cfg["auto_tooltip"].to_bool() && tooltip_.empty() && items_.size() == 1) { - tooltip_ = hotkey::get_description(items_[0]) - + hotkey::get_names(items_[0]) + "\n" + hotkey::get_tooltip(items_[0]); + tooltip_ = hotkey::get_description(items_[0]["id"]) + + hotkey::get_names(items_[0]["id"]) + "\n" + hotkey::get_tooltip(items_[0]["id"]); } else if (cfg["tooltip_name_prepend"].to_bool() && items_.size() == 1) { - tooltip_ = hotkey::get_description(items_[0]) - + hotkey::get_names(items_[0]) + "\n" + tooltip_; + tooltip_ = hotkey::get_description(items_[0]["id"]) + + hotkey::get_names(items_[0]["id"]) + "\n" + tooltip_; } } diff --git a/src/theme.hpp b/src/theme.hpp index ce1ccc4f74fc..dbee093593be 100644 --- a/src/theme.hpp +++ b/src/theme.hpp @@ -244,14 +244,14 @@ class theme const std::string& overlay() const { return overlay_; } - const std::vector& items() const { return items_; } + const std::vector& items() const { return items_; } void set_title(const std::string& new_title) { title_ = new_title; } private: bool button_; bool context_; std::string title_, tooltip_, image_, overlay_; - std::vector items_; + std::vector items_; }; explicit theme(const config& cfg, const SDL_Rect& screen);