From 8901f9adca1112f3d19376d8aeffa6281ad1f06d Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Mon, 23 Jun 2025 08:24:03 +0100 Subject: [PATCH] Fix #14361: Removing a badge filter did not clear it. (#14379) --- src/build_vehicle_gui.cpp | 6 +++++- src/newgrf_badge_gui.cpp | 11 +++++++---- src/newgrf_badge_gui.h | 2 +- src/picker_gui.cpp | 22 ++++++++++++++++------ src/picker_gui.h | 1 + 5 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index e713a7b5ec..9386d903a2 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1896,7 +1896,7 @@ struct BuildVehicleWindow : Window { break; case WID_BV_CONFIGURE_BADGES: { - bool reopen = HandleBadgeConfigurationDropDownClick(static_cast(GSF_TRAINS + this->vehicle_type), BADGE_COLUMNS, index, click_result); + bool reopen = HandleBadgeConfigurationDropDownClick(static_cast(GSF_TRAINS + this->vehicle_type), BADGE_COLUMNS, index, click_result, this->badge_filter_choices); this->ReInit(); @@ -1905,6 +1905,10 @@ struct BuildVehicleWindow : Window { } else { this->CloseChildWindows(WC_DROPDOWN_MENU); } + + /* We need to refresh if a filter is removed. */ + this->eng_list.ForceRebuild(); + this->SetDirty(); break; } diff --git a/src/newgrf_badge_gui.cpp b/src/newgrf_badge_gui.cpp index c36981a7bc..3a92d8e06a 100644 --- a/src/newgrf_badge_gui.cpp +++ b/src/newgrf_badge_gui.cpp @@ -365,14 +365,17 @@ DropDownList BuildBadgeClassConfigurationList(const GUIBadgeClasses &gui_classes * @param class_badge Class badge. * @param click Dropdown click reuslt. */ -static void BadgeClassToggleVisibility(GrfSpecFeature feature, Badge &class_badge, int click_result) +static void BadgeClassToggleVisibility(GrfSpecFeature feature, Badge &class_badge, int click_result, BadgeFilterChoices &choices) { auto config = GetBadgeClassConfiguration(feature); auto it = std::ranges::find(config, class_badge.label, &BadgeClassConfigItem::label); if (it == std::end(config)) return; if (click_result == BADGE_CLICK_TOGGLE_ICON) it->show_icon = !it->show_icon; - if (click_result == BADGE_CLICK_TOGGLE_FILTER) it->show_filter = !it->show_filter; + if (click_result == BADGE_CLICK_TOGGLE_FILTER) { + it->show_filter = !it->show_filter; + if (!it->show_filter) ResetBadgeFilter(choices, class_badge.class_index); + } } /** @@ -442,7 +445,7 @@ static void BadgeClassMoveNext(GrfSpecFeature feature, Badge &class_badge, uint * @param click_result Dropdown click result. * @return true iff the caller should reinitialise their widgets. */ -bool HandleBadgeConfigurationDropDownClick(GrfSpecFeature feature, uint columns, int result, int click_result) +bool HandleBadgeConfigurationDropDownClick(GrfSpecFeature feature, uint columns, int result, int click_result, BadgeFilterChoices &choices) { if (result == INT_MAX) { ResetBadgeClassConfiguration(feature); @@ -461,7 +464,7 @@ bool HandleBadgeConfigurationDropDownClick(GrfSpecFeature feature, uint columns, break; case BADGE_CLICK_TOGGLE_ICON: case BADGE_CLICK_TOGGLE_FILTER: - BadgeClassToggleVisibility(feature, *class_badge, click_result); + BadgeClassToggleVisibility(feature, *class_badge, click_result, choices); break; default: break; diff --git a/src/newgrf_badge_gui.h b/src/newgrf_badge_gui.h index 935c48df22..e73186d951 100644 --- a/src/newgrf_badge_gui.h +++ b/src/newgrf_badge_gui.h @@ -54,7 +54,7 @@ std::unique_ptr MakeDropDownListBadgeItem(const std::shared_pt std::unique_ptr MakeDropDownListBadgeIconItem(const std::shared_ptr &gui_classes, std::span badges, GrfSpecFeature feature, std::optional introduction_date, const Dimension &dim, SpriteID sprite, PaletteID palette, std::string &&str, int value, bool masked = false, bool shaded = false); DropDownList BuildBadgeClassConfigurationList(const class GUIBadgeClasses &badge_class, uint columns, std::span column_separators); -bool HandleBadgeConfigurationDropDownClick(GrfSpecFeature feature, uint columns, int result, int click_result); +bool HandleBadgeConfigurationDropDownClick(GrfSpecFeature feature, uint columns, int result, int click_result, BadgeFilterChoices &choices); std::pair AddBadgeDropdownFilters(NWidgetContainer &container, WidgetID widget, Colours colour, GrfSpecFeature feature); diff --git a/src/picker_gui.cpp b/src/picker_gui.cpp index ecfc4dbc22..68c547ebfb 100644 --- a/src/picker_gui.cpp +++ b/src/picker_gui.cpp @@ -442,7 +442,7 @@ void PickerWindow::OnDropdownSelect(WidgetID widget, int index, int click_result { switch (widget) { case WID_PW_CONFIGURE_BADGES: { - bool reopen = HandleBadgeConfigurationDropDownClick(this->callbacks.GetFeature(), 1, index, click_result); + bool reopen = HandleBadgeConfigurationDropDownClick(this->callbacks.GetFeature(), 1, index, click_result, this->badge_filter_choices); this->ReInit(); @@ -451,6 +451,9 @@ void PickerWindow::OnDropdownSelect(WidgetID widget, int index, int click_result } else { this->CloseChildWindows(WC_DROPDOWN_MENU); } + + /* We need to refresh if a filter is removed. */ + this->InvalidateData({PickerInvalidation::Type, PickerInvalidation::Filter}); break; } @@ -461,9 +464,7 @@ void PickerWindow::OnDropdownSelect(WidgetID widget, int index, int click_result } else { SetBadgeFilter(this->badge_filter_choices, BadgeID(index)); } - this->type_string_filter.bdf.emplace(this->badge_filter_choices); - this->types.SetFilterState(!type_string_filter.IsEmpty() || type_string_filter.bdf.has_value()); - this->InvalidateData(PickerInvalidation::Type); + this->InvalidateData({PickerInvalidation::Type, PickerInvalidation::Filter}); } break; } @@ -474,6 +475,16 @@ void PickerWindow::OnInvalidateData(int data, bool gui_scope) if (!gui_scope) return; PickerInvalidations pi(data); + + if (pi.Test(PickerInvalidation::Filter)) { + if (this->badge_filter_choices.empty()) { + this->type_string_filter.bdf.reset(); + } else { + this->type_string_filter.bdf.emplace(this->badge_filter_choices); + } + this->types.SetFilterState(!type_string_filter.IsEmpty() || type_string_filter.bdf.has_value()); + } + if (pi.Test(PickerInvalidation::Class)) this->classes.ForceRebuild(); if (pi.Test(PickerInvalidation::Type)) this->types.ForceRebuild(); @@ -526,8 +537,7 @@ void PickerWindow::OnEditboxChanged(WidgetID wid) } else { this->type_string_filter.btf.reset(); } - this->types.SetFilterState(!type_string_filter.IsEmpty() || type_string_filter.bdf.has_value()); - this->InvalidateData(PickerInvalidation::Type); + this->InvalidateData({PickerInvalidation::Type, PickerInvalidation::Filter}); break; default: diff --git a/src/picker_gui.h b/src/picker_gui.h index 908d060706..0fd5f6d6bf 100644 --- a/src/picker_gui.h +++ b/src/picker_gui.h @@ -165,6 +165,7 @@ public: Type, ///< Refresh the type list. Position, ///< Update scroll positions. Validate, ///< Validate selected item. + Filter, ///< Update filter state. }; using PickerInvalidations = EnumBitSet;