units dialog (recall, unit list): implement 1.18 filtering (#9902)

adds customization support for filter text
This commit is contained in:
Subhraman Sarkar 2025-02-13 22:47:44 +05:30
parent 0f556cbd79
commit 42dd45cbbd
2 changed files with 64 additions and 2 deletions

View File

@ -183,17 +183,24 @@ void units_dialog::show_list(listbox& list)
column["tooltip"] = tooltip_gen_(i); column["tooltip"] = tooltip_gen_(i);
} }
// if custom filter text generator exists, use it to generate the filter text
if (filter_gen_) {
filter_options_.push_back(filter_gen_(i));
}
for (const auto& [id, gen] : column_generators_) { for (const auto& [id, gen] : column_generators_) {
column["use_markup"] = "true"; column["use_markup"] = "true";
// generate label for ith row and column with 'id' // generate label for ith row and column with 'id'
column["label"] = gen(i); column["label"] = gen(i);
if (id != "unit_image") { if (!filter_gen_ && id != "unit_image") {
filter_fmt << column["label"]; filter_fmt << column["label"];
} }
row_data.emplace(id, column); row_data.emplace(id, column);
} }
filter_options_.push_back(filter_fmt.str()); if (!filter_gen_) {
filter_options_.push_back(filter_fmt.str());
}
list.add_row(row_data); list.add_row(row_data);
} }
@ -596,6 +603,25 @@ std::unique_ptr<units_dialog> units_dialog::build_unit_list_dialog(std::vector<u
return utils::join(unit->trait_names(), ", "); return utils::join(unit->trait_names(), ", ");
}, sort_type::generator); }, sort_type::generator);
dlg->set_filter_generator([&unit_list](std::size_t index) {
const auto& unit = unit_list[index];
const std::string& name = !unit->name().empty() ? unit->name().str() : font::unicode_en_dash;
// 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())
+ " " + unit_type::alignment_description(unit->alignment(), unit->gender());
if(const auto* race = unit->race()) {
filter_text += " " + race->name(unit->gender()) + " " + race->plural_name();
}
for(const std::string& trait : unit->trait_names()) {
filter_text += " " + trait;
}
return filter_text;
});
dlg->on_modified([&unit_list, &rename](std::size_t index) -> const auto& { dlg->on_modified([&unit_list, &rename](std::size_t index) -> const auto& {
auto& unit = unit_list[index]; auto& unit = unit_list[index];
rename.set_active(!unit->unrenamable()); rename.set_active(!unit->unrenamable());
@ -738,6 +764,33 @@ std::unique_ptr<units_dialog> units_dialog::build_recall_dialog(
} }
}); });
dlg->set_filter_generator([recallable, &recall_list](std::size_t index) {
const auto& unit = recall_list[index];
const std::string& name = !unit->name().empty() ? unit->name().str() : font::unicode_en_dash;
// 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())
+ " " + unit_type::alignment_description(unit->alignment(), unit->gender());
if(const auto* race = unit->race()) {
filter_text += " " + race->name(unit->gender()) + " " + race->plural_name();
}
if(recallable(*unit)) {
// This is to allow filtering for recallable units by typing "vvv" in the search box.
// That's intended to be easy to type and unlikely to match unit or type names.
//
// TODO: document this. (Also, implement a "Hide non-recallable units" checkbox.)
filter_text += " vvv";
}
for(const std::string& trait : unit->trait_names()) {
filter_text += " " + trait;
}
return filter_text;
});
dlg->on_modified([&recall_list, &rename](std::size_t index) -> const auto& { dlg->on_modified([&recall_list, &rename](std::size_t index) -> const auto& {
const auto& unit = recall_list[index]; const auto& unit = recall_list[index];
rename.set_active(!unit->unrenamable()); rename.set_active(!unit->unrenamable());

View File

@ -182,6 +182,14 @@ public:
return *this; return *this;
} }
/** Sets the generator function for filter text. */
template<typename Generator>
units_dialog& set_filter_generator(const Generator& generator)
{
filter_gen_ = generator;
return *this;
}
// } -------------------- BUILDERS -------------------- { // } -------------------- BUILDERS -------------------- {
using recruit_msgs_map = std::map<const unit_type*, t_string>; using recruit_msgs_map = std::map<const unit_type*, t_string>;
@ -207,6 +215,7 @@ private:
std::map<std::string_view, std::function<std::string(std::size_t)>> column_generators_; std::map<std::string_view, std::function<std::string(std::size_t)>> column_generators_;
std::function<std::string(std::size_t)> tooltip_gen_; std::function<std::string(std::size_t)> tooltip_gen_;
std::function<std::string(std::size_t)> filter_gen_;
unit_race::GENDER gender_; unit_race::GENDER gender_;
std::string variation_; std::string variation_;