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.
This commit is contained in:
Peter Nelson 2024-05-07 12:13:48 +01:00 committed by Peter Nelson
parent cdc356e7bf
commit b76517816e
4 changed files with 43 additions and 2 deletions

View File

@ -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

View File

@ -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<NWidgetCore>(WID_PW_TYPE_ITEM)->tool_tip = this->callbacks.GetTypeTooltip();
auto *matrix = this->GetWidget<NWidgetMatrix>(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<NWidgetBase>(widget)->GetParentWidget<NWidgetMatrix>()->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<NWidgetBase> 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),

View File

@ -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<PickerItem, std::nullptr_t, PickerFilterData &>;
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.

View File

@ -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.