From b76517816e214694b5ed212f93563ec4ea6afc29 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 7 May 2024 12:13:48 +0100 Subject: [PATCH] Feature: Add "All" filter to build-picker show types from all classes. Toggling the "All" filter causes the class selection to be ignored, so that items from all classes can be displayed together. The class text filter is still applied. This makes it easier to search amongst types for a feature. --- src/lang/english.txt | 3 +++ src/picker_gui.cpp | 35 +++++++++++++++++++++++++++++++++-- src/picker_gui.h | 6 ++++++ src/widgets/picker_widget.h | 1 + 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 66858310f6..62298a8c07 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2797,6 +2797,9 @@ STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP :{BLACK}Select l STR_STATION_BUILD_DRAG_DROP :{BLACK}Drag & Drop STR_STATION_BUILD_DRAG_DROP_TOOLTIP :{BLACK}Build a station using drag & drop +STR_PICKER_MODE_ALL :All +STR_PICKER_MODE_ALL_TOOLTIP :Toggle showing items from all classes + STR_PICKER_STATION_CLASS_TOOLTIP :Select a station class to display STR_PICKER_STATION_TYPE_TOOLTIP :Select a station type to build. Ctrl+Click to add or remove in saved items STR_PICKER_WAYPOINT_CLASS_TOOLTIP :Select a waypoint class to display diff --git a/src/picker_gui.cpp b/src/picker_gui.cpp index a9eda4298f..291532a5c5 100644 --- a/src/picker_gui.cpp +++ b/src/picker_gui.cpp @@ -107,6 +107,8 @@ void PickerWindow::ConstructWindow() this->classes.SetFilterFuncs(_class_filter_funcs); if (this->has_type_picker) { + SetWidgetDisabledState(WID_PW_MODE_ALL, !this->callbacks.HasClassChoice()); + this->GetWidget(WID_PW_TYPE_ITEM)->tool_tip = this->callbacks.GetTypeTooltip(); auto *matrix = this->GetWidget(WID_PW_TYPE_MATRIX); @@ -228,7 +230,9 @@ void PickerWindow::OnClick(Point pt, WidgetID widget, int) auto it = vscroll->GetScrolledItemFromWidget(this->classes, pt.y, this, WID_PW_CLASS_LIST); if (it == this->classes.end()) return; - if (this->callbacks.GetSelectedClass() != *it) { + if (this->callbacks.GetSelectedClass() != *it || HasBit(this->callbacks.mode, PFM_ALL)) { + ClrBit(this->callbacks.mode, PFM_ALL); // Disable showing all. + SetWidgetLoweredState(WID_PW_MODE_ALL, false); this->callbacks.SetSelectedClass(*it); this->InvalidateData(PFI_TYPE | PFI_POSITION | PFI_VALIDATE); } @@ -237,6 +241,12 @@ void PickerWindow::OnClick(Point pt, WidgetID widget, int) break; } + case WID_PW_MODE_ALL: + ToggleBit(this->callbacks.mode, widget - WID_PW_MODE_ALL); + SetWidgetLoweredState(widget, HasBit(this->callbacks.mode, widget - WID_PW_MODE_ALL)); + this->InvalidateData(PFI_TYPE | PFI_POSITION); + break; + /* Type Picker */ case WID_PW_TYPE_ITEM: { int sel = this->GetWidget(widget)->GetParentWidget()->GetCurrentElement(); @@ -268,6 +278,10 @@ void PickerWindow::OnInvalidateData(int data, bool gui_scope) this->BuildPickerTypeList(); if ((data & PFI_VALIDATE) != 0) this->EnsureSelectedTypeIsValid(); if ((data & PFI_POSITION) != 0) this->EnsureSelectedTypeIsVisible(); + + if (this->has_type_picker) { + SetWidgetLoweredState(WID_PW_MODE_ALL, HasBit(this->callbacks.mode, PFM_ALL)); + } } EventState PickerWindow::OnHotkey(int hotkey) @@ -358,9 +372,23 @@ void PickerWindow::BuildPickerTypeList() if (!this->types.NeedRebuild()) return; this->types.clear(); + bool show_all = HasBit(this->callbacks.mode, PFM_ALL); int cls_id = this->callbacks.GetSelectedClass(); - { + if (show_all) { + /* Reserve enough space for everything. */ + int total = 0; + for (int class_index : this->classes) total += this->callbacks.GetTypeCount(class_index); + this->types.reserve(total); + /* Add types in all classes. */ + for (int class_index : this->classes) { + int count = this->callbacks.GetTypeCount(class_index); + for (int i = 0; i < count; i++) { + if (this->callbacks.GetTypeName(class_index, i) == INVALID_STRING_ID) continue; + this->types.emplace_back(this->callbacks.GetPickerItem(class_index, i)); + } + } + } else { /* Add types in only the selected class. */ if (cls_id >= 0 && cls_id < this->callbacks.GetClassCount()) { int count = this->callbacks.GetTypeCount(cls_id); @@ -442,6 +470,9 @@ std::unique_ptr MakePickerTypeWidgets() NWidget(WWT_PANEL, COLOUR_DARK_GREEN), NWidget(WWT_EDITBOX, COLOUR_DARK_GREEN, WID_PW_TYPE_FILTER), SetPadding(2), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_TEXTBTN, COLOUR_DARK_GREEN, WID_PW_MODE_ALL), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_PICKER_MODE_ALL, STR_PICKER_MODE_ALL_TOOLTIP), + EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetScrollbar(WID_PW_TYPE_SCROLL), NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, WID_PW_TYPE_MATRIX), SetPIP(0, 2, 0), SetPadding(WidgetDimensions::unscaled.picker), diff --git a/src/picker_gui.h b/src/picker_gui.h index 861abe0811..e48cc5f269 100644 --- a/src/picker_gui.h +++ b/src/picker_gui.h @@ -79,6 +79,8 @@ public: Listing type_last_sorting = { false, 0 }; ///< Default sorting of #PickerTypeList. Filtering type_last_filtering = { false, 0 }; ///< Default filtering of #PickerTypeList. + + uint8_t mode = 0; ///< Bitmask of \c PickerFilterModes. }; /** Helper for PickerCallbacks when the class system is based on NewGRFClass. */ @@ -115,6 +117,10 @@ using PickerTypeList = GUIList; class PickerWindow : public PickerWindowBase { public: + enum PickerFilterModes { + PFM_ALL = 0, ///< Show all classes. + }; + enum PickerFilterInvalidation { PFI_CLASS = 1U << 0, ///< Refresh the class list. PFI_TYPE = 1U << 1, ///< Refresh the type list. diff --git a/src/widgets/picker_widget.h b/src/widgets/picker_widget.h index 6e89da98e8..fe45a2a427 100644 --- a/src/widgets/picker_widget.h +++ b/src/widgets/picker_widget.h @@ -21,6 +21,7 @@ enum PickerClassWindowWidgets : WidgetID { WID_PW_TYPE_SEL, ///< Stack to hide the type picker. WID_PW_TYPE_FILTER, ///< Text filter. + WID_PW_MODE_ALL, ///< Toggle "Show all" filter mode. WID_PW_TYPE_MATRIX, ///< Matrix with items. WID_PW_TYPE_ITEM, ///< A single item. WID_PW_TYPE_SCROLL, ///< Scrollbar for the matrix.