diff --git a/src/lang/english.txt b/src/lang/english.txt index 66858310f6e8e..62298a8c07e34 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 a9eda4298f6f0..291532a5c54f4 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 861abe08111d3..e48cc5f2692fe 100644 --- a/src/picker_gui.h +++ b/src/picker_gui.h @@ -79,6 +79,8 @@ class PickerCallbacks { 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 6e89da98e8416..fe45a2a427269 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.