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); }