diff --git a/src/picker_gui.cpp b/src/picker_gui.cpp index 1e52dde944..3bc14fb3be 100644 --- a/src/picker_gui.cpp +++ b/src/picker_gui.cpp @@ -150,7 +150,9 @@ static bool TypeIDSorter(PickerItem const &a, PickerItem const &b) /** Filter types by class name. */ static bool TypeTagNameFilter(PickerItem const *item, PickerFilterData &filter) { - if (filter.btf.has_value() && filter.btf->Filter(filter.callbacks->GetTypeBadges(item->class_index, item->index))) return true; + auto badges = filter.callbacks->GetTypeBadges(item->class_index, item->index); + if (filter.bdf.has_value() && !filter.bdf->Filter(badges)) return false; + if (filter.btf.has_value() && filter.btf->Filter(badges)) return true; filter.ResetState(); filter.AddLine(GetString(filter.callbacks->GetTypeName(item->class_index, item->index))); @@ -247,6 +249,12 @@ void PickerWindow::ConstructWindow() void PickerWindow::OnInit() { this->badge_classes = GUIBadgeClasses(this->callbacks.GetFeature()); + + auto container = this->GetWidget(WID_PW_BADGE_FILTER); + this->badge_filters = AddBadgeDropdownFilters(*container, WID_PW_BADGE_FILTER, COLOUR_DARK_GREEN, this->callbacks.GetFeature()); + + this->widget_lookup.clear(); + this->nested_root->FillWidgetLookup(this->widget_lookup); } void PickerWindow::Close(int data) @@ -288,6 +296,15 @@ void PickerWindow::UpdateWidgetSize(WidgetID widget, Dimension &size, const Dime } } +std::string PickerWindow::GetWidgetString(WidgetID widget, StringID stringid) const +{ + if (IsInsideMM(widget, this->badge_filters.first, this->badge_filters.second)) { + return this->GetWidget(widget)->GetStringParameter(this->badge_filter_choices); + } + + return this->Window::GetWidgetString(widget, stringid); +} + void PickerWindow::DrawWidget(const Rect &r, WidgetID widget) const { switch (widget) { @@ -414,6 +431,9 @@ void PickerWindow::OnClick(Point pt, WidgetID widget, int) break; default: + if (IsInsideMM(widget, this->badge_filters.first, this->badge_filters.second)) { + ShowDropDownList(this, this->GetWidget(widget)->GetDropDownList(), -1, widget, 0, false); + } break; } } @@ -435,6 +455,16 @@ void PickerWindow::OnDropdownSelect(WidgetID widget, int index, int click_result } default: + if (IsInsideMM(widget, this->badge_filters.first, this->badge_filters.second)) { + if (index < 0) { + ResetBadgeFilter(this->badge_filter_choices, this->GetWidget(widget)->GetBadgeClassID()); + } 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); + } break; } } @@ -496,7 +526,7 @@ void PickerWindow::OnEditboxChanged(WidgetID wid) } else { this->type_string_filter.btf.reset(); } - this->types.SetFilterState(!type_string_filter.IsEmpty()); + this->types.SetFilterState(!type_string_filter.IsEmpty() || type_string_filter.bdf.has_value()); this->InvalidateData(PickerInvalidation::Type); break; @@ -712,6 +742,8 @@ std::unique_ptr MakePickerTypeWidgets() EndContainer(), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_PW_CONFIGURE_BADGES), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON), SetResize(0, 0), SetFill(0, 1), SetSpriteTip(SPR_EXTRA_MENU, STR_BADGE_CONFIG_MENU_TOOLTIP), EndContainer(), + NWidget(NWID_VERTICAL, NWidContainerFlag{}, WID_PW_BADGE_FILTER), + EndContainer(), NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), NWidget(WWT_TEXTBTN, COLOUR_DARK_GREEN, WID_PW_MODE_ALL), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_PICKER_MODE_ALL, STR_PICKER_MODE_ALL_TOOLTIP), NWidget(WWT_TEXTBTN, COLOUR_DARK_GREEN, WID_PW_MODE_USED), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_PICKER_MODE_USED, STR_PICKER_MODE_USED_TOOLTIP), diff --git a/src/picker_gui.h b/src/picker_gui.h index 629b26342e..908d060706 100644 --- a/src/picker_gui.h +++ b/src/picker_gui.h @@ -146,6 +146,7 @@ public: struct PickerFilterData : StringFilter { const PickerCallbacks *callbacks; ///< Callbacks for filter functions to access to callbacks. std::optional btf; + std::optional bdf; }; using PickerClassList = GUIList; ///< GUIList holding classes to display. @@ -183,6 +184,7 @@ public: void OnInit() override; void Close(int data = 0) override; void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override; + std::string GetWidgetString(WidgetID widget, StringID stringid) const override; void DrawWidget(const Rect &r, WidgetID widget) const override; void OnDropdownSelect(WidgetID widget, int index, int click_result) override; void OnResize() override; @@ -222,6 +224,8 @@ private: void EnsureSelectedTypeIsVisible(); GUIBadgeClasses badge_classes; + std::pair badge_filters{}; + BadgeFilterChoices badge_filter_choices{}; const IntervalTimer yearly_interval = {{TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [this](auto) { this->SetDirty(); diff --git a/src/widgets/picker_widget.h b/src/widgets/picker_widget.h index 97b2dd7a4e..1cc5db48a5 100644 --- a/src/widgets/picker_widget.h +++ b/src/widgets/picker_widget.h @@ -29,8 +29,8 @@ enum PickerClassWindowWidgets : WidgetID { WID_PW_TYPE_SCROLL, ///< Scrollbar for the matrix. WID_PW_TYPE_NAME, ///< Name of selected item. WID_PW_TYPE_RESIZE, ///< Type resize handle. - WID_PW_CONFIGURE_BADGES, ///< Button to configure badges. + WID_PW_BADGE_FILTER, ///< Container for dropdown badge filters. }; #endif /* WIDGETS_PICKER_WIDGET_H */