void unit_recall::rename_unit(window& window) { listbox& list = find_widget<listbox>(&window, "recall_list", false); const int index = list.get_selected_row(); unit& selected_unit = const_cast<unit&>(*recall_list_[index].get()); std::string name = selected_unit.name(); const std::string dialog_title(_("Rename Unit")); const std::string dialog_label(_("Name:")); if(gui2::dialogs::edit_text::execute(dialog_title, dialog_label, name)) { selected_unit.rename(name); find_widget<label>(list.get_row_grid(index), "unit_name", false).set_label(name); filter_options_.erase(filter_options_.begin() + index); std::ostringstream filter_text; filter_text << selected_unit.type_name() << " " << name << " " << std::to_string(selected_unit.level()); for(const std::string& trait : selected_unit.trait_names()) { filter_text << " " << trait; } filter_options_.insert(filter_options_.begin() + index, filter_text.str()); list_item_clicked(window); window.invalidate_layout(); } }
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 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::dismiss_unit(window& window) { LOG_DP << "Recall list units:\n"; dump_recall_list_to_console(recall_list_); listbox& list = find_widget<listbox>(&window, "recall_list", false); const int index = list.get_selected_row(); const unit& u = *recall_list_[index].get(); // If the unit is of level > 1, or is close to advancing, we warn the player about it std::stringstream message; if(u.loyal()) { message << _("This unit is loyal and requires no upkeep.") << " " << (u.gender() == unit_race::MALE ? _("Do you really want to dismiss him?") : _("Do you really want to dismiss her?")); } else if(u.level() > 1) { message << _("This unit is an experienced one, having advanced levels.") << " " << (u.gender() == unit_race::MALE ? _("Do you really want to dismiss him?") : _("Do you really want to dismiss her?")); } else if(u.experience() > u.max_experience()/2) { message << _("This unit is close to advancing a level.") << " " << (u.gender() == unit_race::MALE ? _("Do you really want to dismiss him?") : _("Do you really want to dismiss her?")); } if(!message.str().empty()) { const int res = gui2::show_message(_("Dismiss Unit"), message.str(), message::yes_no_buttons); if(res != gui2::retval::OK) { return; } } recall_list_.erase(recall_list_.begin() + index); // Remove the entry from the dialog list list.remove_row(index); list_item_clicked(window); // Remove the entry from the filter list filter_options_.erase(filter_options_.begin() + index); assert(filter_options_.size() == list.get_item_count()); LOG_DP << "Dismissing a unit, side = " << u.side() << ", id = '" << u.id() << "'\n"; LOG_DP << "That side's recall list:\n"; dump_recall_list_to_console(team_.recall_list()); // Find the unit in the recall list. unit_ptr dismissed_unit = team_.recall_list().find_if_matches_id(u.id()); assert(dismissed_unit); // Record the dismissal, then delete the unit. synced_context::run_and_throw("disband", replay_helper::get_disband(dismissed_unit->id())); // Close the dialog if all units are dismissed if(list.get_item_count() == 0) { window.set_retval(retval::CANCEL); } }
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 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); }