void teditor_resize_map::pre_show(CVideo& /*video*/, twindow& window) { tslider& height = find_widget<tslider>(&window, "height", false); connect_signal_notify_modified(height , boost::bind( &teditor_resize_map::update_expand_direction , this , boost::ref(window))); tslider& width = find_widget<tslider>(&window, "width", false); connect_signal_notify_modified(width , boost::bind( &teditor_resize_map::update_expand_direction , this , boost::ref(window))); std::string name_prefix = "expand"; for (int i = 0; i < 9; ++i) { std::string name = name_prefix + lexical_cast<std::string>(i); direction_buttons_[i] = find_widget<ttoggle_button>( &window, name, false, true); direction_buttons_[i]->set_callback_state_change( dialog_callback<teditor_resize_map , &teditor_resize_map::update_expand_direction>); } direction_buttons_[0]->set_value(true); update_expand_direction(window); }
void tscrollbar_container::finalize_setup() { /***** Setup vertical scrollbar *****/ vertical_scrollbar_grid_ = find_widget<tgrid>(this, "_vertical_scrollbar_grid", false, true); vertical_scrollbar_ = find_widget<tscrollbar_>( vertical_scrollbar_grid_, "_vertical_scrollbar", false, true); connect_signal_notify_modified(*vertical_scrollbar_ , boost::bind( &tscrollbar_container::vertical_scrollbar_moved , this)); /***** Setup horizontal scrollbar *****/ horizontal_scrollbar_grid_ = find_widget<tgrid>(this, "_horizontal_scrollbar_grid", false, true); horizontal_scrollbar_ = find_widget<tscrollbar_>( horizontal_scrollbar_grid_, "_horizontal_scrollbar", false, true); connect_signal_notify_modified(*horizontal_scrollbar_ , boost::bind( &tscrollbar_container::horizontal_scrollbar_moved , this)); /***** Setup the scrollbar buttons *****/ typedef std::pair<std::string, tscrollbar_::tscroll> hack; BOOST_FOREACH(const hack& item, scroll_lookup()) { // Vertical. tclickable_* button = find_widget<tclickable_>( vertical_scrollbar_grid_, item.first, false, false); if(button) { button->connect_click_handler(boost::bind( &tscrollbar_container::scroll_vertical_scrollbar , this , item.second)); } // Horizontal. button = find_widget<tclickable_>( horizontal_scrollbar_grid_, item.first, false, false); if(button) { button->connect_click_handler(boost::bind( &tscrollbar_container::scroll_horizontal_scrollbar , this , item.second)); } }
std::function<void()> bind_status_label( widget* find_in, const std::string& source_id, const std::function<std::string(W&)> value_getter = default_status_value_getter<W>, const std::string& label_id = "") { // If no label ID is provided, use the format source ID + '_label'. const std::string label_id_ = label_id.empty() ? source_id + "_label" : label_id; // Find the source value widget. W& source = find_widget<W>(find_in, source_id, false); // Find the target status label. styled_widget& label = find_widget<styled_widget>(find_in, label_id_, false); const auto update_label = [&, value_getter]() { const std::string value = value_getter(source); label.set_label(value); }; // Bind the callback. connect_signal_notify_modified(source, std::bind(update_label)); // Set initial value. update_label(); return update_label; }
void tdata_manage::pre_show(CVideo& /*video*/, twindow& window) { assert(txtFilter_); ttext_box* filter = find_widget<ttext_box>(&window, "txtFilter", false, true); window.keyboard_capture(filter); filter->set_text_changed_callback( boost::bind(&tdata_manage::filter_text_changed, this, _1, _2)); tlistbox& list = find_widget<tlistbox>(&window, "persist_list", false); window.keyboard_capture(&list); #ifdef GUI2_EXPERIMENTAL_LISTBOX connect_signal_notify_modified(list, boost::bind(&tdata_manage::list_item_clicked, this, boost::ref(window))); #else list.set_callback_value_change( dialog_callback<tdata_manage, &tdata_manage::list_item_clicked>); #endif { cursor::setter cur(cursor::WAIT); games_ = savegame::get_saves_list(); } fill_game_list(window, games_); connect_signal_mouse_left_click( find_widget<tbutton>(&window, "clear", false), boost::bind(&tdata_manage::delete_button_callback, this, boost::ref(window))); }
/** * Sets a callback on a widget of the current dialog. * - Arg 1: function. * - Args 2..n: path of strings and integers. */ int intf_set_dialog_callback(lua_State *L) { gui2::twidget *w = find_widget(L, 2, true); scoped_dialog::callback_map &m = scoped_dialog::current->callbacks; scoped_dialog::callback_map::iterator i = m.find(w); if (i != m.end()) { lua_pushstring(L , dlgclbkKey); lua_rawget(L, LUA_REGISTRYINDEX); lua_pushnil(L); lua_rawseti(L, -2, i->second); lua_pop(L, 1); m.erase(i); } if (lua_isnil(L, 1)) return 0; if (gui2::tclickable_ *c = dynamic_cast<gui2::tclickable_ *>(w)) { static tdialog_callback_wrapper wrapper; c->connect_click_handler(boost::bind( &tdialog_callback_wrapper::forward , wrapper , w)); } else if (gui2::tselectable_ *s = dynamic_cast<gui2::tselectable_ *>(w)) { s->set_callback_state_change(&dialog_callback); } #ifdef GUI2_EXPERIMENTAL_LISTBOX else if (gui2::tlist *l = dynamic_cast<gui2::tlist *>(w)) { static tdialog_callback_wrapper wrapper; connect_signal_notify_modified(*l , boost::bind( &tdialog_callback_wrapper::forward , wrapper , w)); } #else else if (gui2::tlistbox *l = dynamic_cast<gui2::tlistbox *>(w)) { l->set_callback_value_change(&dialog_callback); } #endif else if (gui2::ttree_view *tv = dynamic_cast<gui2::ttree_view *>(w)) { tv->set_selection_change_callback(&dialog_callback); } else return luaL_argerror(L, lua_gettop(L), "unsupported widget"); lua_pushstring(L , dlgclbkKey); lua_rawget(L, LUA_REGISTRYINDEX); int n = lua_rawlen(L, -1) + 1; m[w] = n; lua_pushvalue(L, 1); lua_rawseti(L, -2, n); lua_pop(L, 1); return 0; }
void tunit_recruit::pre_show(twindow& window) { tlistbox& list = find_widget<tlistbox>(&window, "recruit_list", false); #ifdef GUI2_EXPERIMENTAL_LISTBOX connect_signal_notify_modified(*list, std::bind(&tunit_recruit::list_item_clicked, *this, std::ref(window))); #else list.set_callback_value_change( dialog_callback<tunit_recruit, &tunit_recruit::list_item_clicked>); #endif window.keyboard_capture(&list); connect_signal_mouse_left_click( find_widget<tbutton>(&window, "show_help", false), std::bind(&tunit_recruit::show_help, this, std::ref(window))); for(const auto& recruit : recruit_list_) { std::map<std::string, string_map> row_data; string_map column; std::string image_string = recruit->image() + "~RC(" + recruit->flag_rgb() + ">" + team::get_side_color_index(team_.side()) + ")"; int wb_gold = 0; if(resources::controller) { if(const std::shared_ptr<wb::manager>& whiteb = resources::controller->get_whiteboard()) { wb::future_map future; // So gold takes into account planned spending wb_gold = whiteb->get_spent_gold_for(team_.side()); } } const bool can_afford = recruit->cost() <= team_.gold() - wb_gold; const std::string cost_string = std::to_string(recruit->cost()); column["use_markup"] = "true"; column["label"] = image_string; row_data.emplace("unit_image", column); column["label"] = can_afford_unit(recruit->type_name(), can_afford); row_data.emplace("unit_type", column); column["label"] = can_afford_unit(cost_string, can_afford); row_data.emplace("unit_cost", column); list.add_row(row_data); } list_item_clicked(window); }
void tmp_create_game::pre_show(twindow& window) { find_widget<tminimap>(&window, "minimap", false).set_config(&cfg_); tlistbox& list = find_widget<tlistbox>(&window, "map_list", false); #ifdef GUI2_EXPERIMENTAL_LISTBOX connect_signal_notify_modified(list, boost::bind(&tmp_create_game::update_map, *this, boost::ref(window))); #else list.set_callback_value_change( dialog_callback<tmp_create_game, &tmp_create_game::update_map>); #endif // Load option (might turn it into a button later). string_map item; item.insert(std::make_pair("label", _("Load Game"))); item.insert(std::make_pair("tooltip", _("Load Game..."))); list.add_row(item); // User maps /* FIXME implement user maps std::vector<std::string> maps; filesystem::get_files_in_dir(filesystem::get_user_data_dir() + "/editor/maps", &maps, nullptr, filesystem::FILE_NAME_ONLY); for(const auto& map : maps) { std::map<std::string, t_string> item; item.insert(std::make_pair("label", map)); list->add_row(item); } */ // Standard maps int i = 0; for(const auto & map : cfg_.child_range("multiplayer")) { if(map["allow_new_game"].to_bool(true)) { string_map item; item.insert(std::make_pair("label", map["name"].str())); item.insert(std::make_pair("tooltip", map["name"].str())); list.add_row(item); // This hack is needed since the next item is too wide to fit. // and the scrollbar can't truncate text yet. if(++i == 46) { break; } } } update_map_settings(window); }
void tcore_selection::pre_show(twindow& window) { /***** Setup core list. *****/ tlistbox& list = find_widget<tlistbox>(&window, "core_list", false); #ifdef GUI2_EXPERIMENTAL_LISTBOX connect_signal_notify_modified( list, std::bind(&tcore_selection::core_selected, this, std::ref(window))); #else list.set_callback_value_change( dialog_callback<tcore_selection, &tcore_selection::core_selected>); #endif window.keyboard_capture(&list); /***** Setup core details. *****/ tmulti_page& multi_page = find_widget<tmulti_page>(&window, "core_details", false); for(const auto & core : cores_) { /*** Add list item ***/ string_map list_item; std::map<std::string, string_map> list_item_item; list_item["label"] = core["image"]; list_item_item.insert(std::make_pair("image", list_item)); list_item["label"] = core["name"]; list_item_item.insert(std::make_pair("name", list_item)); list.add_row(list_item_item); tgrid* grid = list.get_row_grid(list.get_item_count() - 1); assert(grid); /*** Add detail item ***/ string_map detail_item; std::map<std::string, string_map> detail_page; detail_item["label"] = core["description"]; detail_item["use_markup"] = "true"; detail_page.insert(std::make_pair("description", detail_item)); multi_page.add_page(detail_page); } list.select_row(choice_, true); core_selected(window); }
void bind(twindow& window) { DBG_GUI << "Main: Binding widgets and callbacks\n"; model_.sides_list = &find_widget<tlistbox>(&window, "sides_list", false); model_.nicks_list = &find_widget<tlistbox>(&window, "nicks_list", false); #ifdef GUI2_EXPERIMENTAL_LISTBOX connect_signal_notify_modified( *model_.sides_list, std::bind(&tmp_change_control::view:: handle_sides_list_item_clicked, this, std::ref(window))); connect_signal_notify_modified( *model_.nicks_list, std::bind(&tmp_change_control::view:: handle_nicks_list_item_clicked, this, std::ref(window))); #else model_.sides_list->set_callback_value_change( dialog_view_callback<tmp_change_control, tmp_change_control::view, &tmp_change_control::view:: handle_sides_list_item_clicked>); model_.nicks_list->set_callback_value_change( dialog_view_callback<tmp_change_control, tmp_change_control::view, &tmp_change_control::view:: handle_nicks_list_item_clicked>); #endif }
void tgame_load::pre_show(CVideo& /*video*/, twindow& window) { find_widget<tminimap>(&window, "minimap", false).set_config(&cache_config_); sheet_.insert(std::make_pair(LOCAL_PAGE, find_widget<ttoggle_button>(&window, "local", false, true))); sheet_.insert(std::make_pair(NETWORK_PAGE, find_widget<ttoggle_button>(&window, "network", false, true))); for (std::map<int, ttoggle_button*>::iterator it = sheet_.begin(); it != sheet_.end(); ++ it) { it->second->set_callback_state_change(boost::bind(&tgame_load::sheet_toggled, this, _1)); it->second->set_data(it->first); } connect_signal_mouse_left_click( find_widget<tbutton>(&window, "delete", false) , boost::bind( &tgame_load::delete_button_callback , this , boost::ref(window))); connect_signal_mouse_left_click( find_widget<tbutton>(&window, "xmit", false) , boost::bind( &tgame_load::xmit_button_callback , this , boost::ref(window))); savegame_list_ = find_widget<tlistbox>(&window, "savegame_list", false, true); sheet_.begin()->second->set_value(true); swap_page(window, LOCAL_PAGE, false); #ifdef GUI2_EXPERIMENTAL_LISTBOX connect_signal_notify_modified(*list, boost::bind( &tgame_load::list_item_clicked , *this , boost::ref(window))); #else savegame_list_->set_callback_value_change( dialog_callback<tgame_load, &tgame_load::list_item_clicked>); #endif if (disp_.in_game()) { find_widget<tbutton>(&window, "xmit", false).set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "local", false).set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "network", false).set_visible(twidget::INVISIBLE); } }
void listbox::finalize(builder_grid_const_ptr header, builder_grid_const_ptr footer, const std::vector<std::map<std::string, string_map>>& list_data) { // "Inherited." scrollbar_container::finalize_setup(); assert(generator_); if(header) { swap_grid(&get_grid(), content_grid(), header->build(), "_header_grid"); } grid& p = find_widget<grid>(this, "_header_grid", false); for(unsigned i = 0, max = std::max(p.get_cols(), p.get_rows()); i < max; ++i) { // // TODO: I had to change this to case to a toggle_button in order to use a signal handler. // Should probably look into a way to make it more general like it was before (used to be // cast to selectable_item). // // - vultraz, 2017-08-23 // if(toggle_button* selectable = find_widget<toggle_button>(&p, "sort_" + std::to_string(i), false, false)) { // Register callback to sort the list. connect_signal_notify_modified(*selectable, std::bind(&listbox::order_by_column, this, i, _1)); if(orders_.size() < max) { orders_.resize(max); } orders_[i].first = selectable; } } if(footer) { swap_grid(&get_grid(), content_grid(), footer->build(), "_footer_grid"); } generator_->create_items(-1, list_builder_, list_data, std::bind(&listbox::list_item_clicked, this, _1)); swap_grid(nullptr, content_grid(), generator_, "_list_grid"); }
void tgame_load::pre_show(CVideo& /*video*/, twindow& window) { assert(txtFilter_); find_widget<tminimap>(&window, "minimap", false).set_config(&cache_config_); ttext_box* filter = find_widget<ttext_box>( &window, "txtFilter", false, true); window.keyboard_capture(filter); filter->set_text_changed_callback(boost::bind( &tgame_load::filter_text_changed, this, _1, _2)); tlistbox* list = find_widget<tlistbox>( &window, "savegame_list", false, true); window.keyboard_capture(list); #ifdef GUI2_EXPERIMENTAL_LISTBOX connect_signal_notify_modified(*list, boost::bind( &tgame_load::list_item_clicked , *this , boost::ref(window))); #else list->set_callback_value_change( dialog_callback<tgame_load, &tgame_load::list_item_clicked>); #endif { cursor::setter cur(cursor::WAIT); games_ = savegame::get_saves_list(); } fill_game_list(window, games_); connect_signal_mouse_left_click( find_widget<tbutton>(&window, "delete", false) , boost::bind( &tgame_load::delete_button_callback , this , boost::ref(window))); display_savegame(window); }
void bind(twindow& window) { LOG_CHAT_LOG << "Entering tchat_log::view::bind" << std::endl; model_.msg_label = &find_widget<tcontrol>(&window, "msg", false); model_.page_number = &find_widget<tslider>(&window, "page_number", false); connect_signal_notify_modified( *model_.page_number, std::bind(&view::handle_page_number_changed, this, std::ref(window))); model_.previous_page = &find_widget<tbutton>(&window, "previous_page", false); model_.previous_page->connect_click_handler( std::bind(&view::previous_page, this, std::ref(window))); model_.next_page = &find_widget<tbutton>(&window, "next_page", false); model_.next_page->connect_click_handler( std::bind(&view::next_page, this, std::ref(window))); model_.filter = &find_widget<ttext_box>(&window, "filter", false); model_.filter->set_text_changed_callback( std::bind(&view::filter, this, std::ref(window))); window.keyboard_capture(model_.filter); model_.copy_button = &find_widget<tbutton>(&window, "copy", false); connect_signal_mouse_left_click( *model_.copy_button, std::bind(&view::handle_copy_button_clicked, this, std::ref(window))); if (!desktop::clipboard::available()) { model_.copy_button->set_active(false); model_.copy_button->set_tooltip(_("Clipboard support not found, contact your packager")); } model_.page_label = &find_widget<tcontrol>(&window, "page_label", false); LOG_CHAT_LOG << "Exiting tchat_log::view::bind" << std::endl; }
std::function<void()> bind_status_label(twidget& find_in, const std::string& id, const std::function<std::string(W&)> value_getter = default_value_getter<W>, const std::string& label_id = "") { const std::string label_id_ = label_id.empty() ? id + "_label" : label_id; W& source = find_widget<W>(&find_in, id, false); tcontrol& label = find_widget<tcontrol>(&find_in, label_id_, false); const auto update_label = [&, value_getter]() { const std::string value = value_getter(source); label.set_label(value); }; // Bind the callback connect_signal_notify_modified(source, std::bind(update_label)); // Set initial value update_label(); return update_label; }
void custom_tod::pre_show(window& window) { assert(!tods_.empty()); tod_red_field_ = find_widget<slider>(&window, "tod_red", false, true); tod_green_field_ = find_widget<slider>(&window, "tod_green", false, true); tod_blue_field_ = find_widget<slider>(&window, "tod_blue", false, true); current_tod_name_ = find_widget<text_box>(&window, "tod_name", false, true); current_tod_id_ = find_widget<text_box>(&window, "tod_id", false, true); current_tod_image_ = find_widget<image>(&window, "current_tod_image", false, true); current_tod_mask_ = find_widget<image>(&window, "current_tod_mask", false, true); current_tod_sound_ = find_widget<label>(&window, "current_sound", false, true); current_tod_number_ = find_widget<label>(&window, "tod_number", false, true); connect_signal_mouse_left_click(find_widget<button>(&window, "image_button", false), std::bind(&custom_tod::select_file, this, get_selected_tod().image, "data/core/images/misc", "image", std::ref(window))); connect_signal_mouse_left_click(find_widget<button>(&window, "mask_button", false), std::bind(&custom_tod::select_file, this, get_selected_tod().image_mask, "data/core/images", "mask", std::ref(window))); connect_signal_mouse_left_click(find_widget<button>(&window, "sound_button", false), std::bind(&custom_tod::select_file, this, get_selected_tod().sounds, "data/core/sounds/ambient", "sound", std::ref(window))); connect_signal_mouse_left_click( find_widget<button>(&window, "next_tod", false), std::bind(&custom_tod::do_next_tod, this, std::ref(window))); connect_signal_mouse_left_click( find_widget<button>(&window, "previous_tod", false), std::bind(&custom_tod::do_prev_tod, this, std::ref(window))); connect_signal_mouse_left_click( find_widget<button>(&window, "new", false), std::bind(&custom_tod::do_new_tod, this, std::ref(window))); connect_signal_mouse_left_click( find_widget<button>(&window, "delete", false), std::bind(&custom_tod::do_delete_tod, this, std::ref(window))); connect_signal_notify_modified( *(lawful_bonus_field_->get_widget()), std::bind(&custom_tod::update_lawful_bonus, this, std::ref(window))); connect_signal_notify_modified( *tod_red_field_, std::bind(&custom_tod::update_tod_display, this, std::ref(window))); connect_signal_notify_modified( *tod_green_field_, std::bind(&custom_tod::update_tod_display, this, std::ref(window))); connect_signal_notify_modified( *tod_blue_field_, std::bind(&custom_tod::update_tod_display, this, std::ref(window))); for(size_t i = 0; i < tods_.size(); ++i) { time_of_day& tod = tods_[i]; const int r = tod_red_field_->get_value(); const int g = tod_green_field_->get_value(); const int b = tod_blue_field_->get_value(); if(tod.color.r == r && tod.color.g == g && tod.color.b == b) { current_tod_ = i; update_selected_tod_info(window); return; } } update_selected_tod_info(window); }
void tlobby_main::pre_show(twindow& window) { SCOPE_LB; gamelistbox_ = find_widget<tlistbox>(&window, "game_list", false, true); #ifdef GUI2_EXPERIMENTAL_LISTBOX connect_signal_notify_modified( *gamelistbox_, std::bind(&tlobby_main::gamelist_change_callback, *this, std::ref(window))); #else gamelistbox_->set_callback_value_change( dialog_callback<tlobby_main, &tlobby_main::gamelist_change_callback>); #endif window.keyboard_capture(gamelistbox_); player_list_.init(window); player_list_.sort_by_name->set_value(preferences::playerlist_sort_name()); player_list_.sort_by_relation->set_value(preferences::playerlist_sort_relation()); player_list_.update_sort_icons(); player_list_.sort_by_name->set_callback_state_change( std::bind(&tlobby_main::player_filter_callback, this, _1)); player_list_.sort_by_relation->set_callback_state_change( std::bind(&tlobby_main::player_filter_callback, this, _1)); window.set_enter_disabled(true); window.set_escape_disabled(true); // A new key handler to deal with escape in a different manner. window.connect_signal<event::SDL_KEY_DOWN>( std::bind(&tlobby_main::signal_handler_key_down, this, _5, _3, _4), event::tdispatcher::front_pre_child); window_ = &window; chatbox_ = find_widget<tchatbox>(&window, "chat", false, true); chatbox_->set_lobby_info(lobby_info_); chatbox_->set_wesnothd_connection(wesnothd_connection_); chatbox_->set_active_window_changed_callback([this]() { player_list_dirty_ = true; }); find_widget<tbutton>(&window, "create", false).set_retval(CREATE); connect_signal_mouse_left_click( find_widget<tbutton>(&window, "refresh", false), std::bind(&tlobby_main::refresh_button_callback, this, std::ref(window))); connect_signal_mouse_left_click( find_widget<tbutton>(&window, "show_preferences", false), std::bind(&tlobby_main::show_preferences_button_callback, this, std::ref(window))); connect_signal_mouse_left_click( find_widget<tbutton>(&window, "join_global", false), std::bind(&tlobby_main::join_global_button_callback, this, std::ref(window))); find_widget<tbutton>(&window, "join_global", false).set_active(false); connect_signal_mouse_left_click( find_widget<tbutton>(&window, "observe_global", false), std::bind(&tlobby_main::observe_global_button_callback, this, std::ref(window))); find_widget<tbutton>(&window, "observe_global", false).set_active(false); tmenu_button& replay_options = find_widget<tmenu_button>(&window, "replay_options", false); if(preferences::skip_mp_replay()) { replay_options.set_selected(1); } if(preferences::blindfold_replay()) { replay_options.set_selected(2); } replay_options.connect_click_handler( std::bind(&tlobby_main::skip_replay_changed_callback, this, std::ref(window))); filter_friends_ = find_widget<ttoggle_button>(&window, "filter_with_friends", false, true); filter_ignored_ = find_widget<ttoggle_button>(&window, "filter_without_ignored", false, true); filter_slots_ = find_widget<ttoggle_button>(&window, "filter_vacant_slots", false, true); filter_invert_ = find_widget<ttoggle_button>(&window, "filter_invert", false, true); filter_text_ = find_widget<ttext_box>(&window, "filter_text", false, true); filter_friends_->set_callback_state_change( std::bind(&tlobby_main::game_filter_change_callback, this, _1)); filter_ignored_->set_callback_state_change( std::bind(&tlobby_main::game_filter_change_callback, this, _1)); filter_slots_->set_callback_state_change( std::bind(&tlobby_main::game_filter_change_callback, this, _1)); filter_invert_->set_callback_state_change( std::bind(&tlobby_main::game_filter_change_callback, this, _1)); connect_signal_pre_key_press( *filter_text_, std::bind(&tlobby_main::game_filter_keypress_callback, this, _5)); chatbox_->room_window_open("lobby", true); chatbox_->active_window_changed(); game_filter_reload(); // Force first update to be directly. tlobby_main::network_handler(); lobby_update_timer_ = add_timer( game_config::lobby_network_timer, std::bind(&tlobby_main::network_handler, this), true); // Set up Lua plugin context plugins_context_.reset(new plugins_context("Multiplayer Lobby")); plugins_context_->set_callback("join", [&, this](const config&) { if(do_game_join(get_game_index_from_id(selected_game_id_), false)) { window.set_retval(JOIN); } }, true); plugins_context_->set_callback("observe", [&, this](const config&) { if(do_game_join(get_game_index_from_id(selected_game_id_), true)) { window.set_retval(OBSERVE); } }, true); plugins_context_->set_callback("create", [this, &window](const config&) { window.set_retval(CREATE); }, true); plugins_context_->set_callback("quit", [&window](const config&) { window.set_retval(twindow::CANCEL); }, false); plugins_context_->set_callback("chat", [this](const config& cfg) { chatbox_->send_chat_message(cfg["message"], false); }, true); plugins_context_->set_callback("select_game", [this](const config& cfg) { selected_game_id_ = cfg.has_attribute("id") ? cfg["id"].to_int() : lobby_info_.games()[cfg["index"].to_int()]->id; }, true); plugins_context_->set_accessor("game_list", [this](const config&) { return lobby_info_.gamelist(); }); plugins_context_->set_accessor("game_config", [this](const config&) { return game_config_; }); }
void tgame_version::pre_show(twindow& window) { string_map i18n_syms; // // General information. // tcontrol& version_label = find_widget<tcontrol>(&window, "version", false); i18n_syms["version"] = game_config::revision; version_label.set_label(VGETTEXT("Version $version", i18n_syms)); tcontrol& os_label = find_widget<tcontrol>(&window, "os", false); i18n_syms["os"] = desktop::os_version(); os_label.set_label(VGETTEXT("Running on $os", i18n_syms)); tbutton& copy_all = find_widget<tbutton>(&window, "copy_all", false); connect_signal_mouse_left_click( copy_all, std::bind(&tgame_version::report_copy_callback, this)); // // Game paths tab. // for(const auto & path_ent : path_map_) { const std::string& path_id = path_ent.first; const std::string& path_path = path_ent.second; ttext_& path_w = find_widget<ttext_>(&window, path_wid_stem_ + path_id, false); tbutton& copy_w = find_widget<tbutton>( &window, copy_wid_stem_ + path_id, false); tbutton& browse_w = find_widget<tbutton>( &window, browse_wid_stem_ + path_id, false); path_w.set_value(path_path); path_w.set_active(false); connect_signal_mouse_left_click( copy_w, std::bind(&tgame_version::copy_to_clipboard_callback, this, path_path)); connect_signal_mouse_left_click( browse_w, std::bind(&tgame_version::browse_directory_callback, this, path_path)); if(!desktop::open_object_is_supported()) { // No point in displaying these on platforms that can't do // open_object(). browse_w.set_visible(tcontrol::tvisible::invisible); } if(!desktop::clipboard::available()) { copy_w.set_active(false); copy_w.set_tooltip(_("Clipboard support not found, contact your packager")); } } #ifndef _WIN32 tgrid& w32_options_grid = find_widget<tgrid>(&window, "win32_paths", false); w32_options_grid.set_visible(twidget::tvisible::invisible); #else tbutton& stderr_button = find_widget<tbutton>(&window, "open_stderr", false); connect_signal_mouse_left_click( stderr_button, std::bind(&tgame_version::browse_directory_callback, this, log_path_)); stderr_button.set_active(!log_path_.empty()); #endif // // Build info tab. // std::map<std::string, string_map> list_data; tlistbox& deps_listbox = find_widget<tlistbox>(&window, "deps_listbox", false); for(const auto & dep : deps_) { list_data["dep_name"]["label"] = dep[0]; list_data["dep_build_version"]["label"] = dep[1]; // The build version is always known, but runtime version isn't, esp. // for header-only libraries like Boost for which the concept does not // apply. if(!dep[2].empty()) { list_data["dep_rt_version"]["label"] = dep[2]; } else { list_data["dep_rt_version"]["label"] = _("version^N/A"); } deps_listbox.add_row(list_data); } deps_listbox.select_row(0); list_data.clear(); // // Features tab. // tlistbox& opts_listbox = find_widget<tlistbox>(&window, "opts_listbox", false); for(const auto & opt : opts_) { list_data["opt_name"]["label"] = opt.name; if(opt.enabled) { list_data["opt_status"]["label"] = text_feature_on; } else { list_data["opt_status"]["label"] = text_feature_off; } list_data["opt_status"]["use_markup"] = "true"; opts_listbox.add_row(list_data); } opts_listbox.select_row(0); list_data.clear(); // // Set-up page stack and auxiliary controls last. // tstacked_widget& pager = find_widget<tstacked_widget>(&window, "tabs_container", false); pager.select_layer(0); tlistbox& tab_bar = find_widget<tlistbox>(&window, "tab_bar", false); window.keyboard_capture(&tab_bar); const unsigned tab_count = tab_bar.get_item_count(); VALIDATE(tab_count == pager.get_layer_count(), "Tab bar and container size mismatch"); #ifdef GUI2_EXPERIMENTAL_LISTBOX connect_signal_notify_modified(tab_bar, std::bind(&tgame_version::tab_switch_callback, *this, std::ref(window))); #else tab_bar.set_callback_value_change( dialog_callback<tgame_version, &tgame_version::tab_switch_callback>); #endif }
void tcampaign_selection::pre_show(twindow& window) { if(new_widgets || true) { /***** Setup campaign tree. *****/ ttree_view& tree = find_widget<ttree_view>(&window, "campaign_tree", false); tree.set_selection_change_callback( std::bind(&tcampaign_selection::campaign_selected, this, std::ref(window))); window.keyboard_capture(&tree); string_map tree_group_field; std::map<std::string, string_map> tree_group_item; /***** Setup campaign details. *****/ tmulti_page& multi_page = find_widget<tmulti_page>(&window, "campaign_details", false); unsigned id = 0; for(const auto & level : engine_.get_levels_by_type_unfiltered(ng::level::TYPE::SP_CAMPAIGN)) { const config& campaign = level->data(); /*** Add tree item ***/ tree_group_field["label"] = campaign["icon"]; tree_group_item["icon"] = tree_group_field; tree_group_field["label"] = campaign["name"]; tree_group_item["name"] = tree_group_field; tree_group_field["label"] = campaign["completed"].to_bool() ? "misc/laurel.png" : "misc/blank-hex.png"; tree_group_item["victory"] = tree_group_field; tree.add_node("campaign", tree_group_item).set_id(std::to_string(id++)); /*** Add detail item ***/ string_map detail_item; std::map<std::string, string_map> detail_page; detail_item["label"] = campaign["description"]; detail_item["use_markup"] = "true"; if(!campaign["description_alignment"].empty()) { detail_item["text_alignment"] = campaign["description_alignment"]; } detail_page.emplace("description", detail_item); detail_item["label"] = campaign["image"]; detail_page.emplace("image", detail_item); multi_page.add_page(detail_page); } if (!engine_.get_const_extras_by_type(ng::create_engine::MOD).empty()) { tree_group_field["label"] = "Modifications"; tree_group_item["tree_view_node_label"] = tree_group_field; //tree_group_item["tree_view_node_label"] = tree_group_field; ttree_view_node& mods_node = tree.add_node("campaign_group", tree_group_item); std::vector<std::string> enabled = engine_.active_mods(); id = 0; tree_group_item.clear(); for(const auto& mod : engine_.get_const_extras_by_type(ng::create_engine::MOD)) { bool active = std::find(enabled.begin(), enabled.end(), mod->id) != enabled.end(); /*** Add tree item ***/ tree_group_field["label"] = mod->name; tree_group_item["checkb"] = tree_group_field; ttree_view_node & node = mods_node.add_child("modification", tree_group_item); ttoggle_button* checkbox = dynamic_cast<ttoggle_button*>(node.find("checkb", true)); VALIDATE(checkbox, missing_widget("checkb")); checkbox->set_value(active); checkbox->set_label(mod->name); checkbox->set_callback_state_change(std::bind(&tcampaign_selection::mod_toggled, this, id, _1)); ++id; } } } else { /***** Hide the tree view. *****/ if(ttree_view* tree = find_widget<ttree_view>(&window, "campaign_tree", false, false)) { tree->set_visible(twidget::tvisible::invisible); } /***** Setup campaign list. *****/ tlistbox& list = find_widget<tlistbox>(&window, "campaign_list", false); #ifdef GUI2_EXPERIMENTAL_LISTBOX connect_signal_notify_modified( list, std::bind(&tcampaign_selection::campaign_selected, this, std::ref(window))); #else list.set_callback_value_change( dialog_callback<tcampaign_selection, &tcampaign_selection::campaign_selected>); #endif window.keyboard_capture(&list); /***** Setup campaign details. *****/ tmulti_page& multi_page = find_widget<tmulti_page>(&window, "campaign_details", false); for(const auto & level : engine_.get_levels_by_type_unfiltered(ng::level::TYPE::SP_CAMPAIGN)) { const config& campaign = level->data(); /*** Add list item ***/ string_map list_item; std::map<std::string, string_map> list_item_item; list_item["label"] = campaign["icon"]; list_item_item.emplace("icon", list_item); list_item["label"] = campaign["name"]; list_item_item.emplace("name", list_item); tgrid* grid = &list.add_row(list_item_item); assert(grid); twidget* widget = grid->find("victory", false); if(widget && !campaign["completed"].to_bool()) { widget->set_visible(twidget::tvisible::hidden); } /*** Add detail item ***/ string_map detail_item; std::map<std::string, string_map> detail_page; detail_item["use_markup"] = "true"; detail_item["label"] = campaign["description"]; detail_page.emplace("description", detail_item); detail_item["label"] = campaign["image"]; detail_page.emplace("image", detail_item); multi_page.add_page(detail_page); } } campaign_selected(window); /***** Setup advanced settings button *****/ tbutton* advanced_settings_button = find_widget<tbutton>(&window, "advanced_settings", false, false); if(advanced_settings_button) { advanced_settings_button->connect_click_handler( std::bind(&tcampaign_selection::show_settings, this, std::ref(window.video()))); } }
void teditor_settings::pre_show(CVideo& /*video*/, twindow& window) { assert(!tods_.empty()); current_tod_label_ = find_widget<tlabel>( &window, "current_tod", false, true); current_tod_image_ = find_widget<tlabel>( &window, "current_tod_image", false, true); custom_tod_toggle_ = find_widget<ttoggle_button>( &window, "custom_tod_toggle", false, true); custom_tod_auto_refresh_ = find_widget<ttoggle_button>( &window, "custom_tod_auto_refresh", false, true); tbutton& next_tod_button = find_widget<tbutton>( &window, "next_tod", false); connect_signal_mouse_left_click(next_tod_button, boost::bind( &teditor_settings::do_next_tod , this , boost::ref(window))); tbutton& apply_button = find_widget<tbutton>( &window, "apply", false); connect_signal_mouse_left_click(apply_button, boost::bind( &teditor_settings::update_tod_display , this , boost::ref(window))); custom_tod_toggle_->set_callback_state_change( dialog_callback<teditor_settings , &teditor_settings::update_selected_tod_info>); connect_signal_notify_modified(*(custom_tod_red_field_->widget()) , boost::bind( &teditor_settings::slider_update_callback , this , boost::ref(window))); connect_signal_notify_modified(*(custom_tod_green_field_->widget()) , boost::bind( &teditor_settings::slider_update_callback , this , boost::ref(window))); connect_signal_notify_modified(*(custom_tod_blue_field_->widget()) , boost::bind( &teditor_settings::slider_update_callback , this , boost::ref(window))); for (size_t i = 0; i < tods_.size(); ++i) { time_of_day& tod = tods_[i]; const int r = custom_tod_red_field_->get_widget_value(window); const int g = custom_tod_green_field_->get_widget_value(window); const int b = custom_tod_blue_field_->get_widget_value(window); if (tod.color.r == r && tod.color.g == g && tod.color.b == b) { current_tod_ = i; custom_tod_toggle_->set_value(false); update_selected_tod_info(window); can_update_display_ = true; return; } } /* custom tod */ custom_tod_toggle_->set_value(true); update_selected_tod_info(window); can_update_display_ = true; }
void tunit_create::pre_show(twindow& window) { ttoggle_button& male_toggle = find_widget<ttoggle_button>(&window, "male_toggle", false); ttoggle_button& female_toggle = find_widget<ttoggle_button>(&window, "female_toggle", false); gender_toggle.add_member(&male_toggle, unit_race::MALE); gender_toggle.add_member(&female_toggle, unit_race::FEMALE); gender_toggle.set_member_states(last_gender); gender_toggle.set_callback_on_value_change( dialog_callback<tunit_create, &tunit_create::gender_toggle_callback>); tlistbox& list = find_widget<tlistbox>(&window, "unit_type_list", false); ttext_box* filter = find_widget<ttext_box>(&window, "filter_box", false, true); filter->set_text_changed_callback( std::bind(&tunit_create::filter_text_changed, this, _1, _2)); window.keyboard_capture(filter); window.add_to_keyboard_chain(&list); #ifdef GUI2_EXPERIMENTAL_LISTBOX connect_signal_notify_modified(*list, std::bind(&tunit_create::list_item_clicked, *this, std::ref(window))); #else list.set_callback_value_change( dialog_callback<tunit_create, &tunit_create::list_item_clicked>); #endif list.clear(); for(const auto & i : unit_types.types()) { if(i.second.do_not_list()) continue; // Make sure this unit type is built with the data we need. unit_types.build_unit_type(i.second, unit_type::FULL); units_.push_back(&i.second); std::map<std::string, string_map> row_data; string_map column; column["label"] = units_.back()->race()->plural_name(); row_data.emplace("race", column); column["label"] = units_.back()->type_name(); row_data.emplace("unit_type", column); list.add_row(row_data); // Select the previous choice, if any. if(choice_.empty() != true && choice_ == i.first) { list.select_row(list.get_item_count() - 1); } } if(units_.empty()) { ERR_GUI_G << "no unit types found for unit create dialog; not good" << std::endl; } list.register_sorting_option(0, [this](const int i) { return (*units_[i]).race()->plural_name().str(); }); list.register_sorting_option(1, [this](const int i) { return (*units_[i]).type_name().str(); }); list_item_clicked(window); }
void unit_recall::pre_show(window& window) { label& title = find_widget<label>(&window, "title", true); title.set_label(title.get_label() + get_title_suffix(team_.side())); text_box* filter = find_widget<text_box>(&window, "filter_box", false, true); filter->set_text_changed_callback( std::bind(&unit_recall::filter_text_changed, this, _1, _2)); listbox& list = find_widget<listbox>(&window, "recall_list", false); connect_signal_notify_modified(list, std::bind(&unit_recall::list_item_clicked, this, std::ref(window))); list.clear(); window.keyboard_capture(filter); window.add_to_keyboard_chain(&list); connect_signal_mouse_left_click( find_widget<button>(&window, "rename", false), std::bind(&unit_recall::rename_unit, this, std::ref(window))); connect_signal_mouse_left_click( find_widget<button>(&window, "dismiss", false), std::bind(&unit_recall::dismiss_unit, this, std::ref(window))); connect_signal_mouse_left_click( find_widget<button>(&window, "show_help", false), std::bind(&unit_recall::show_help, this)); for(const unit_const_ptr& unit : recall_list_) { std::map<std::string, string_map> row_data; string_map column; std::string mods = unit->image_mods(); if(unit->can_recruit()) { mods += "~BLIT(" + unit::leader_crown() + ")"; } for(const std::string& overlay : unit->overlays()) { mods += "~BLIT(" + overlay + ")"; } column["use_markup"] = "true"; column["label"] = unit->absolute_image() + mods; row_data.emplace("unit_image", column); column["label"] = unit->type_name(); row_data.emplace("unit_type", column); column["label"] = format_cost_string(unit->recall_cost(), team_.recall_cost()); row_data.emplace("unit_recall_cost", column); const std::string& name = !unit->name().empty() ? unit->name().str() : font::unicode_en_dash; column["label"] = name; row_data.emplace("unit_name", column); column["label"] = format_level_string(unit->level()); row_data.emplace("unit_level", column); std::stringstream exp_str; exp_str << font::span_color(unit->xp_color()); if(unit->can_advance()) { exp_str << unit->experience() << "/" << unit->max_experience(); } else { exp_str << font::unicode_en_dash; } exp_str << "</span>"; column["label"] = exp_str.str(); row_data.emplace("unit_experience", column); // Since the table widgets use heavy formatting, we save a bare copy // of certain options to filter on. std::string filter_text = unit->type_name() + " " + name + " " + std::to_string(unit->level()); std::string traits; for(const std::string& trait : unit->trait_names()) { traits += (traits.empty() ? "" : "\n") + trait; filter_text += " " + trait; } column["label"] = !traits.empty() ? traits : font::unicode_en_dash; row_data.emplace("unit_traits", column); list.add_row(row_data); filter_options_.push_back(filter_text); } list.register_translatable_sorting_option(0, [this](const int i) { return recall_list_[i]->type_name().str(); }); list.register_translatable_sorting_option(1, [this](const int i) { return recall_list_[i]->name().str(); }); list.register_sorting_option(2, [this](const int i) { const unit& u = *recall_list_[i]; return std::make_tuple(u.level(), -static_cast<int>(u.experience_to_advance())); }); list.register_sorting_option(3, [this](const int i) { return recall_list_[i]->experience(); }); list.register_translatable_sorting_option(4, [this](const int i) { return !recall_list_[i]->trait_names().empty() ? recall_list_[i]->trait_names().front().str() : ""; }); list.set_active_sorting_option(sort_last.first >= 0 ? sort_last : sort_default, true); list_item_clicked(window); }
void tlobby_main::pre_show(twindow& window) { SCOPE_LB; roomlistbox_ = find_widget<tlistbox>(&window, "room_list", false, true); #ifdef GUI2_EXPERIMENTAL_LISTBOX connect_signal_notify_modified( *roomlistbox_, std::bind(&tlobby_main::room_switch_callback, *this, std::ref(window))); #else roomlistbox_->set_callback_value_change( dialog_callback<tlobby_main, &tlobby_main::room_switch_callback>); #endif gamelistbox_ = find_widget<tlistbox>(&window, "game_list", false, true); #ifdef GUI2_EXPERIMENTAL_LISTBOX connect_signal_notify_modified( *gamelistbox_, std::bind(&tlobby_main::gamelist_change_callback, *this, std::ref(window))); #else gamelistbox_->set_callback_value_change( dialog_callback<tlobby_main, &tlobby_main::gamelist_change_callback>); #endif window.keyboard_capture(gamelistbox_); player_list_.init(window); player_list_.sort_by_name->set_value(preferences::playerlist_sort_name()); player_list_.sort_by_relation->set_value(preferences::playerlist_sort_relation()); player_list_.update_sort_icons(); player_list_.sort_by_name->set_callback_state_change( std::bind(&tlobby_main::player_filter_callback, this, _1)); player_list_.sort_by_relation->set_callback_state_change( std::bind(&tlobby_main::player_filter_callback, this, _1)); chat_log_container_ = find_widget<tmulti_page>(&window, "chat_log_container", false, true); window.set_enter_disabled(true); window_ = &window; chat_input_ = find_widget<ttext_box>(&window, "chat_input", false, true); assert(chat_input_); connect_signal_pre_key_press( *chat_input_, std::bind(&tlobby_main::chat_input_keypress_callback, this, _3, _4, _5, std::ref(window))); connect_signal_mouse_left_click( find_widget<tbutton>(&window, "create", false), std::bind(&tlobby_main::create_button_callback, this, std::ref(window))); connect_signal_mouse_left_click( find_widget<tbutton>(&window, "refresh", false), std::bind(&tlobby_main::refresh_button_callback, this, std::ref(window))); connect_signal_mouse_left_click( find_widget<tbutton>(&window, "show_preferences", false), std::bind(&tlobby_main::show_preferences_button_callback, this, std::ref(window))); connect_signal_mouse_left_click( find_widget<tbutton>(&window, "join_global", false), std::bind(&tlobby_main::join_global_button_callback, this, std::ref(window))); find_widget<tbutton>(&window, "join_global", false).set_active(false); connect_signal_mouse_left_click( find_widget<tbutton>(&window, "observe_global", false), std::bind(&tlobby_main::observe_global_button_callback, this, std::ref(window))); find_widget<tbutton>(&window, "observe_global", false).set_active(false); ttoggle_button& skip_replay = find_widget<ttoggle_button>(&window, "skip_replay", false); skip_replay.set_value(preferences::skip_mp_replay()); skip_replay.set_callback_state_change( std::bind(&tlobby_main::skip_replay_changed_callback, this, _1)); filter_friends_ = find_widget<ttoggle_button>(&window, "filter_with_friends", false, true); filter_ignored_ = find_widget<ttoggle_button>(&window, "filter_without_ignored", false, true); filter_slots_ = find_widget<ttoggle_button>(&window, "filter_vacant_slots", false, true); filter_invert_ = find_widget<ttoggle_button>(&window, "filter_invert", false, true); filter_text_ = find_widget<ttext_box>(&window, "filter_text", false, true); filter_friends_->set_callback_state_change( std::bind(&tlobby_main::game_filter_change_callback, this, _1)); filter_ignored_->set_callback_state_change( std::bind(&tlobby_main::game_filter_change_callback, this, _1)); filter_slots_->set_callback_state_change( std::bind(&tlobby_main::game_filter_change_callback, this, _1)); filter_invert_->set_callback_state_change( std::bind(&tlobby_main::game_filter_change_callback, this, _1)); connect_signal_pre_key_press( *filter_text_, std::bind(&tlobby_main::game_filter_keypress_callback, this, _5)); room_window_open("lobby", true); active_window_changed(); game_filter_reload(); // Force first update to be directly. tlobby_main::network_handler(); lobby_update_timer_ = add_timer( game_config::lobby_network_timer, std::bind(&tlobby_main::network_handler, this), true); }
void tscrollbar_container::finalize_setup() { /***** Setup vertical scrollbar *****/ vertical_scrollbar_grid_ = find_widget<tgrid>(this, "_vertical_scrollbar_grid", false, true); vertical_scrollbar_ = find_widget<tscrollbar_>( vertical_scrollbar_grid_, "_vertical_scrollbar", false, true); connect_signal_notify_modified( *vertical_scrollbar_, std::bind(&tscrollbar_container::vertical_scrollbar_moved, this)); /***** Setup horizontal scrollbar *****/ horizontal_scrollbar_grid_ = find_widget<tgrid>( this, "_horizontal_scrollbar_grid", false, true); horizontal_scrollbar_ = find_widget<tscrollbar_>( horizontal_scrollbar_grid_, "_horizontal_scrollbar", false, true); connect_signal_notify_modified( *horizontal_scrollbar_, std::bind(&tscrollbar_container::horizontal_scrollbar_moved, this)); /***** Setup the scrollbar buttons *****/ for(const auto & item : scroll_lookup()) { // Vertical. tclickable_* button = find_widget<tclickable_>( vertical_scrollbar_grid_, item.first, false, false); if(button) { button->connect_click_handler(std::bind( &tscrollbar_container::scroll_vertical_scrollbar, this, item.second)); } // Horizontal. button = find_widget<tclickable_>( horizontal_scrollbar_grid_, item.first, false, false); if(button) { button->connect_click_handler(std::bind( &tscrollbar_container::scroll_horizontal_scrollbar, this, item.second)); } } /***** Setup the content *****/ content_ = new tspacer(); content_->set_definition("default"); content_grid_ = dynamic_cast<tgrid*>( grid().swap_child("_content_grid", content_, true)); assert(content_grid_); content_grid_->set_parent(this); /***** Let our subclasses initialize themselves. *****/ finalize_subclass(); }
void mp_staging::add_side_node(window& window, ng::side_engine_ptr side) { tree_view& tree = find_widget<tree_view>(&window, "side_list", false); static const std::map<std::string, string_map> empty_map; std::map<std::string, string_map> data; string_map item; item["label"] = std::to_string(side->index() + 1); data.emplace("side_number", item); // TODO: don't hardcode meganta? item["label"] = "units/unknown-unit.png~RC(magenta>" + std::to_string(side->color() + 1) + ")"; data.emplace("leader_image", item); item["label"] = "icons/icon-random.png"; data.emplace("leader_gender", item); // Check to see whether we've added a toplevel tree node for this team. If not, add one if(team_tree_map_.find(side->team_name()) == team_tree_map_.end()) { std::map<std::string, string_map> data; string_map item; item["label"] = (formatter() << _("Team:") << " " << side->user_team_name()).str(); data.emplace("tree_view_node_label", item); tree_view_node& team_node = tree.add_node("team_header", data); team_node.add_sibling("side_spacer", empty_map); team_tree_map_[side->team_name()] = &team_node; } tree_view_node& node = team_tree_map_[side->team_name()]->add_child("side_panel", data); side_tree_map_[side] = &node; grid& row_grid = node.get_grid(); update_leader_display(side, row_grid); // Status variables const bool fls = connect_engine_.force_lock_settings(); const bool ums = connect_engine_.params().use_map_settings; const bool lock_gold = side->cfg()["gold_lock"].to_bool(fls); const bool lock_income = side->cfg()["income_lock"].to_bool(fls); const bool lock_team = side->cfg()["team_lock"].to_bool(fls); const bool lock_color = side->cfg()["color_lock"].to_bool(fls); const bool saved_game = connect_engine_.params().saved_game; // // AI Algorithm // int selection = 0; // We use an index-based loop in order to get the index of the selected option std::vector<config> ai_options; for(unsigned i = 0; i < ai_algorithms_.size(); i++) { ai_options.push_back(config_of("label", ai_algorithms_[i]->text)); if(ai_algorithms_[i]->id == side->ai_algorithm()) { selection = i; } } menu_button& ai_selection = find_widget<menu_button>(&row_grid, "ai_controller", false); ai_selection.set_values(ai_options, selection); ai_selection.connect_click_handler(std::bind(&mp_staging::on_ai_select, this, side, std::ref(ai_selection))); on_ai_select(side, ai_selection); // // Controller // std::vector<config> controller_names; for(const auto& controller : side->controller_options()) { controller_names.push_back(config_of("label", controller.second)); } menu_button& controller_selection = find_widget<menu_button>(&row_grid, "controller", false); controller_selection.set_values(controller_names, side->current_controller_index()); controller_selection.set_active(controller_names.size() > 1); controller_selection.connect_click_handler(std::bind(&mp_staging::on_controller_select, this, side, std::ref(row_grid))); on_controller_select(side, row_grid); // // Leader controls // button& leader_select = find_widget<button>(&row_grid, "select_leader", false); leader_select.set_active(!saved_game); connect_signal_mouse_left_click(leader_select, std::bind(&mp_staging::select_leader_callback, this, std::ref(window), side, std::ref(row_grid))); // // Team // std::vector<config> team_names; for(const auto& team : side->player_teams()) { team_names.push_back(config_of("label", team)); } menu_button& team_selection = find_widget<menu_button>(&row_grid, "side_team", false); // HACK: side->team() does not get its index from side->player_teams(), but rather side->team_names(). // As such, the index is off if there is only 1 playable team. This is a hack to make sure the menu_button // widget doesn't assert with the invalid initial selection. The connect_engine should be fixed once the GUI1 // dialog is dropped team_selection.set_values(team_names, std::min<int>(team_names.size() - 1, side->team())); team_selection.set_active(!saved_game); team_selection.connect_click_handler(std::bind(&mp_staging::on_team_select, this, std::ref(window), side, std::ref(team_selection), _3, _4)); // // Colors // std::vector<config> color_options; for(const auto& color : side->color_options()) { color_options.push_back(config_of ("label", font::get_color_string_pango(color)) ("icon", (formatter() << "misc/status.png~RC(magenta>" << color << ")").str()) ); } menu_button& color_selection = find_widget<menu_button>(&row_grid, "side_color", false); color_selection.set_values(color_options, side->color()); color_selection.set_active(!saved_game); color_selection.set_use_markup(true); color_selection.connect_click_handler(std::bind(&mp_staging::on_color_select, this, side, std::ref(row_grid))); // // Gold and Income // slider& slider_gold = find_widget<slider>(&row_grid, "side_gold_slider", false); slider_gold.set_value(side->cfg()["gold"].to_int(100)); connect_signal_notify_modified(slider_gold, std::bind( &mp_staging::on_side_slider_change<&ng::side_engine::set_gold>, this, side, std::ref(slider_gold))); slider& slider_income = find_widget<slider>(&row_grid, "side_income_slider", false); slider_income.set_value(side->cfg()["income"]); connect_signal_notify_modified(slider_income, std::bind( &mp_staging::on_side_slider_change<&ng::side_engine::set_income>, this, side, std::ref(slider_income))); // TODO: maybe display the saved values if(saved_game) { slider_gold.set_visible(widget::visibility::invisible); slider_income.set_visible(widget::visibility::invisible); } // // Gold, income, team, and color are only suggestions unless explicitly locked // if(!saved_game && ums) { team_selection.set_active(!lock_team); color_selection.set_active(!lock_color); slider_gold.set_active(!lock_gold); slider_income.set_active(!lock_income); } }
void tunit_create::pre_show(CVideo& /*video*/, twindow& window) { ttoggle_button& male_toggle = find_widget<ttoggle_button>(&window, "male_toggle", false); ttoggle_button& female_toggle = find_widget<ttoggle_button>(&window, "female_toggle", false); tlistbox& list = find_widget<tlistbox>(&window, "unit_type_list", false); ttext_box* filter = find_widget<ttext_box>(&window, "filter_box", false, true); filter->set_text_changed_callback( boost::bind(&tunit_create::filter_text_changed, this, _1, _2)); #ifdef GUI2_EXPERIMENTAL_LISTBOX connect_signal_notify_modified(*list, boost::bind(&tunit_create::list_item_clicked, *this, boost::ref(window))); #else list.set_callback_value_change( dialog_callback<tunit_create, &tunit_create::list_item_clicked>); #endif window.keyboard_capture(&list); connect_signal_mouse_left_click( find_widget<tbutton>(&window, "type_profile", false), boost::bind(&tunit_create::profile_button_callback, this, boost::ref(window))); male_toggle.set_callback_state_change( dialog_callback<tunit_create, &tunit_create::gender_toggle_callback>); female_toggle.set_callback_state_change( dialog_callback<tunit_create, &tunit_create::gender_toggle_callback>); update_male_female_toggles(male_toggle, female_toggle, gender_); list.clear(); FOREACH(const AUTO & i, unit_types.types()) { if(i.second.do_not_list()) continue; // Make sure this unit type is built with the data we need. unit_types.build_unit_type(i.second, unit_type::WITHOUT_ANIMATIONS); units_.push_back(&i.second); std::map<std::string, string_map> row_data; string_map column; column["label"] = units_.back()->race()->plural_name(); row_data.insert(std::make_pair("race", column)); column["label"] = units_.back()->type_name(); row_data.insert(std::make_pair("unit_type", column)); list.add_row(row_data); // Select the previous choice, if any. if(choice_.empty() != true && choice_ == i.first) { list.select_row(list.get_item_count() - 1); } } if(units_.empty()) { ERR_GUI_G << "no unit types found for unit create dialog; not good" << std::endl; } std::vector<tgenerator_::torder_func> order_funcs(2); order_funcs[0] = boost::bind(&tunit_create::compare_race, this, _1, _2); order_funcs[1] = boost::bind(&tunit_create::compare_race_rev, this, _1, _2); list.set_column_order(0, order_funcs); order_funcs[0] = boost::bind(&tunit_create::compare_type, this, _1, _2); order_funcs[1] = boost::bind(&tunit_create::compare_type_rev, this, _1, _2); list.set_column_order(1, order_funcs); list_item_clicked(window); }
void mp_options_helper::display_custom_options(const std::string& type, int node_position, const config& cfg) { // Needed since some compilers don't like passing just {} static const std::map<std::string, string_map> empty_map; // This ensures that any game, era, or mod with no options doesn't get an entry in the visible_options_ // vector and prevents invalid options from different games, era, or mods being created when the options // config is created. if(!cfg.has_child("options")) { return; } visible_options_.push_back({type, cfg["id"]}); // Get the node vector for this specific source type node_vector& type_node_vector = node_data_map_[type].nodes; for(const auto& options : cfg.child_range("options")) { std::map<std::string, string_map> data; string_map item; item["label"] = cfg["name"]; data.emplace("tree_view_node_label", item); tree_view_node& option_node = options_tree_.add_node("option_node", data, node_position); type_node_vector.push_back(&option_node); for(const config::any_child& opt : options.all_children_range()) { data.clear(); item.clear(); const config& option_cfg = opt.cfg; const auto add_name = [&](const std::string& id) { item["label"] = option_cfg["name"]; data.emplace(id, item); }; config::attribute_value val; if(opt.key == "checkbox") { add_name("option_checkbox"); toggle_button* checkbox; std::tie(checkbox, val) = add_node_and_get_widget<toggle_button>(option_node, "option_checkbox", data, option_cfg); checkbox->set_value(val.to_bool()); connect_signal_notify_modified(*checkbox, std::bind(&mp_options_helper::update_options_data_map<toggle_button>, this, checkbox, visible_options_.back())); } else if(opt.key == "spacer") { option_node.add_child("options_spacer_node", empty_map); } else if(opt.key == "choice" || opt.key == "combo") { if(opt.key == "combo") { deprecated_message("combo", DEP_LEVEL::FOR_REMOVAL, {1, 15, 0}, "Use [choice] instead."); } if(!option_cfg.has_child("item")) { continue; } add_name("menu_button_label"); std::vector<config> combo_items; std::vector<std::string> combo_values; for(auto i : option_cfg.child_range("item")) { // Comboboxes expect this key to be 'label' not 'name' i["label"] = i["name"]; combo_items.push_back(i); combo_values.push_back(i["value"]); } menu_button* menu; std::tie(menu, val) = add_node_and_get_widget<menu_button>(option_node, "option_menu_button", data, option_cfg); // Needs to be called before set_selected menu->set_values(combo_items); auto iter = std::find(combo_values.begin(), combo_values.end(), val.str()); if(iter != combo_values.end()) { menu->set_selected(std::distance(combo_values.begin(), iter)); } connect_signal_notify_modified(*menu, std::bind(&mp_options_helper::update_options_data_map_menu_button, this, menu, visible_options_.back(), option_cfg)); } else if(opt.key == "slider") { add_name("slider_label"); slider* slide; std::tie(slide, val) = add_node_and_get_widget<slider>(option_node, "option_slider", data, option_cfg); slide->set_value_range(option_cfg["min"].to_int(), option_cfg["max"].to_int()); slide->set_step_size(option_cfg["step"].to_int(1)); slide->set_value(val.to_int()); connect_signal_notify_modified(*slide, std::bind(&mp_options_helper::update_options_data_map<slider>, this, slide, visible_options_.back())); } else if(opt.key == "entry") { add_name("text_entry_label"); text_box* textbox; std::tie(textbox, val) = add_node_and_get_widget<text_box>(option_node, "option_text_entry", data, option_cfg); textbox->set_value(val.str()); textbox->set_text_changed_callback( std::bind(&mp_options_helper::update_options_data_map<text_box>, this, textbox, visible_options_.back())); } } // Add the Defaults button at the end tree_view_node& node = option_node.add_child("options_default_button", empty_map); connect_signal_mouse_left_click(find_widget<button>(&node, "reset_option_values", false), std::bind(&mp_options_helper::reset_options_data, this, visible_options_.back(), std::placeholders::_3, std::placeholders::_4)); } }
void tcampaign_selection::pre_show(CVideo& /*video*/, twindow& window) { /***** Setup campaign list. *****/ tlistbox& list = find_widget<tlistbox>(&window, "campaign_list", false); #ifdef GUI2_EXPERIMENTAL_LISTBOX connect_signal_notify_modified(list, boost::bind( &tcampaign_selection::campaign_selected , this , boost::ref(window))); #else list.set_callback_value_change(dialog_callback <tcampaign_selection , &tcampaign_selection::campaign_selected>); #endif window.keyboard_capture(&list); /***** Setup campaign details. *****/ tmulti_page& multi_page = find_widget<tmulti_page>( &window, "campaign_details", false); size_t n = 0; foreach (const config &c, campaigns_) { if (c["id"] == "tutorial") { n ++; continue; } /*** Add list item ***/ string_map list_item; std::map<std::string, string_map> list_item_item; list_item["label"] = c["icon"]; list_item_item.insert(std::make_pair("icon", list_item)); list_item["label"] = c["name"]; list_item_item.insert(std::make_pair("name", list_item)); list.add_row(list_item_item); tgrid* grid = list.get_row_grid(list.get_item_count() - 1); assert(grid); tcontrol* widget = dynamic_cast<tcontrol*>(grid->find("mode", false)); if (widget) { const std::string& mode = c["mode"].str(); if (mode == "rpg") { widget->set_label("misc/mode-rpg.png"); } else if (mode == "tower") { widget->set_label("misc/mode-tower.png"); } } ttoggle_panel* toggle = dynamic_cast<ttoggle_panel*>(grid->find("_toggle", true)); toggle->set_data(n ++); /*** Add detail item ***/ string_map detail_item; std::map<std::string, string_map> detail_page; detail_item["label"] = c["description"]; detail_item["use_markup"] = "true"; detail_page.insert(std::make_pair("description", detail_item)); detail_item["label"] = c["image"]; detail_page.insert(std::make_pair("image", detail_item)); multi_page.add_page(detail_page); } campaign_selected(window); }
void mp_staging::add_side_node(window& window, ng::side_engine_ptr side) { std::map<std::string, string_map> data; string_map item; item["label"] = std::to_string(side->index() + 1); data.emplace("side_number", item); // TODO: don't hardcode magenta? item["label"] = "units/unknown-unit.png~RC(magenta>" + side->color_id() + ")"; data.emplace("leader_image", item); item["label"] = "icons/icon-random.png"; data.emplace("leader_gender", item); tree_view_node& node = team_tree_map_[side->team_name()]->add_child("side_panel", data, get_side_node_position(side)); side_tree_map_[side] = &node; grid& row_grid = node.get_grid(); update_leader_display(side, row_grid); // Status variables const bool fls = connect_engine_.force_lock_settings(); const bool ums = connect_engine_.params().use_map_settings; const bool lock_gold = side->cfg()["gold_lock"].to_bool(fls); const bool lock_income = side->cfg()["income_lock"].to_bool(fls); const bool lock_team = side->cfg()["team_lock"].to_bool(fls); const bool lock_color = side->cfg()["color_lock"].to_bool(fls); const bool saved_game = connect_engine_.params().saved_game == mp_game_settings::SAVED_GAME_MODE::MIDGAME; // // AI Algorithm // int selection = 0; // We use an index-based loop in order to get the index of the selected option std::vector<config> ai_options; // If this is loading a saved game, we add an option at the beginning of the menu. // This results in a mismatch between the indices of ai_options and ai_algorithms_ // that we need to account for later. if(saved_game) { ai_options.emplace_back("label", "Keep saved AI"); } for(unsigned i = 0; i < ai_algorithms_.size(); ++i) { ai_options.emplace_back("label", ai_algorithms_[i]->text); if(ai_algorithms_[i]->id == side->ai_algorithm()) { selection = i; } } menu_button& ai_selection = find_widget<menu_button>(&row_grid, "ai_controller", false); ai_selection.set_values(ai_options, selection); connect_signal_notify_modified(ai_selection, std::bind(&mp_staging::on_ai_select, this, side, std::ref(ai_selection), saved_game)); on_ai_select(side, ai_selection, saved_game); // // Controller // std::vector<config> controller_names; for(const auto& controller : side->controller_options()) { controller_names.emplace_back("label", controller.second); } menu_button& controller_selection = find_widget<menu_button>(&row_grid, "controller", false); controller_selection.set_values(controller_names, side->current_controller_index()); controller_selection.set_active(controller_names.size() > 1); connect_signal_notify_modified(controller_selection, std::bind(&mp_staging::on_controller_select, this, side, std::ref(row_grid))); on_controller_select(side, row_grid); // // Leader controls // button& leader_select = find_widget<button>(&row_grid, "select_leader", false); //todo: shouldn't this also be disabled when the flg settings are locked. leader_select.set_active(!saved_game); connect_signal_mouse_left_click(leader_select, std::bind(&mp_staging::select_leader_callback, this, side, std::ref(row_grid))); // // Team // std::vector<config> team_names; unsigned initial_team_selection = 0; for(unsigned i = 0; i < connect_engine_.team_data().size(); ++i) { const ng::connect_engine::team_data_pod& tdata = connect_engine_.team_data()[i]; if(!tdata.is_player_team && !game_config::debug) { continue; } config entry; entry["label"] = t_string::from_serialized(tdata.user_team_name); // Since we're not necessarily displaying every every team, we need to store the // index a displayed team has in the connect_engine's team_data vector. This is // then utilized in the click callback. entry["team_index"] = i; team_names.push_back(std::move(entry)); // Since, again, every team might not be displayed, and side_engine::team() returns // an index into the team_data vector, get an initial selection index for the menu // adjusted for the displayed named. if(side->team() == i) { initial_team_selection = team_names.size() - 1; } } menu_button& team_selection = find_widget<menu_button>(&row_grid, "side_team", false); team_selection.set_values(team_names, initial_team_selection); //todo: shouldn't this also be disabled when team settings are locked. team_selection.set_active(!saved_game); connect_signal_notify_modified(team_selection, std::bind(&mp_staging::on_team_select, this, std::ref(window), side, std::ref(team_selection))); // // Colors // std::vector<config> color_options; for(const auto& color : side->color_options()) { color_options.emplace_back( "label", font::get_color_string_pango(color), "icon", (formatter() << "misc/status.png~RC(magenta>" << color << ")").str() ); } menu_button& color_selection = find_widget<menu_button>(&row_grid, "side_color", false); color_selection.set_values(color_options, side->color()); color_selection.set_active(!saved_game); color_selection.set_use_markup(true); connect_signal_notify_modified(color_selection, std::bind(&mp_staging::on_color_select, this, side, std::ref(row_grid))); // // Gold and Income // const auto slider_setup_helper = [](slider& slider, const int value) { // For the gold and income sliders, the usual min and max values are set in // the dialog WML. However, if a side specifies a value out of that range, // we adjust the bounds to accommodate it. slider.set_value_range( std::min(value, slider.get_minimum_value()), std::max(value, slider.get_maximum_value()) ); slider.set_value(value); }; slider& slider_gold = find_widget<slider>(&row_grid, "side_gold_slider", false); slider_setup_helper(slider_gold, side->gold()); connect_signal_notify_modified(slider_gold, std::bind( &mp_staging::on_side_slider_change<&ng::side_engine::set_gold>, this, side, std::ref(slider_gold))); slider& slider_income = find_widget<slider>(&row_grid, "side_income_slider", false); slider_setup_helper(slider_income, side->income()); connect_signal_notify_modified(slider_income, std::bind( &mp_staging::on_side_slider_change<&ng::side_engine::set_income>, this, side, std::ref(slider_income))); // TODO: maybe display the saved values if(saved_game) { slider_gold.set_visible(widget::visibility::invisible); slider_income.set_visible(widget::visibility::invisible); } // // Gold, income, team, and color are only suggestions unless explicitly locked // if(!saved_game && ums) { team_selection.set_active(!lock_team); color_selection.set_active(!lock_color); slider_gold.set_active(!lock_gold); slider_income.set_active(!lock_income); } }