diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 2899829fc4..164c8fcfd5 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -218,17 +218,26 @@ class CompanyStationsWindow : public Window { protected: /* Runtime saved values */ - static Listing last_sorting; - static byte facilities; // types of stations of interest - static bool include_empty; // whether we should include stations without waiting cargo - static const CargoTypes cargo_filter_max; - static CargoTypes cargo_filter; // bitmap of cargo types to include + struct FilterState { + Listing last_sorting; + byte facilities; ///< types of stations of interest + bool include_empty; ///< whether we should include stations without waiting cargo + CargoTypes cargoes; ///< bitmap of cargo types to include + }; + + static inline FilterState initial_state = { + {false, 0}, + FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK, + true, + ALL_CARGOTYPES, + }; /* Constants for sorting stations */ static const StringID sorter_names[]; static GUIStationList::SortFunction * const sorter_funcs[]; - GUIStationList stations{cargo_filter}; + FilterState filter; + GUIStationList stations{filter.cargoes}; Scrollbar *vscroll; uint rating_width; @@ -247,19 +256,19 @@ protected: for (const Station *st : Station::Iterate()) { if (st->owner == owner || (st->owner == OWNER_NONE && HasStationInUse(st->index, true, owner))) { - if (this->facilities & st->facilities) { // only stations with selected facilities + if (this->filter.facilities & st->facilities) { // only stations with selected facilities int num_waiting_cargo = 0; for (CargoID j = 0; j < NUM_CARGO; j++) { if (st->goods[j].HasRating()) { num_waiting_cargo++; // count number of waiting cargo - if (HasBit(this->cargo_filter, j)) { + if (HasBit(this->filter.cargoes, j)) { this->stations.push_back(st); break; } } } /* stations without waiting cargo */ - if (num_waiting_cargo == 0 && this->include_empty) { + if (num_waiting_cargo == 0 && this->filter.include_empty) { this->stations.push_back(st); } } @@ -350,8 +359,12 @@ protected: public: CompanyStationsWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc) { - this->stations.SetListing(this->last_sorting); - this->stations.SetSortFuncs(this->sorter_funcs); + /* Load initial filter state. */ + this->filter = CompanyStationsWindow::initial_state; + if (this->filter.cargoes == ALL_CARGOTYPES) this->filter.cargoes = _cargo_mask; + + this->stations.SetListing(this->filter.last_sorting); + this->stations.SetSortFuncs(CompanyStationsWindow::sorter_funcs); this->stations.ForceRebuild(); this->stations.NeedResort(); this->SortStationsList(); @@ -363,25 +376,27 @@ public: uint8_t index = 0; for (const CargoSpec *cs : _sorted_standard_cargo_specs) { - if (HasBit(this->cargo_filter, cs->Index())) { + if (HasBit(this->filter.cargoes, cs->Index())) { this->LowerWidget(WID_STL_CARGOSTART + index); } index++; } - if (this->cargo_filter == this->cargo_filter_max) this->cargo_filter = _cargo_mask; + if (this->filter.cargoes == ALL_CARGOTYPES) this->filter.cargoes = _cargo_mask; for (uint i = 0; i < 5; i++) { - if (HasBit(this->facilities, i)) this->LowerWidget(i + WID_STL_TRAIN); + if (HasBit(this->filter.facilities, i)) this->LowerWidget(i + WID_STL_TRAIN); } - this->SetWidgetLoweredState(WID_STL_NOCARGOWAITING, this->include_empty); + this->SetWidgetLoweredState(WID_STL_NOCARGOWAITING, this->filter.include_empty); this->GetWidget(WID_STL_SORTDROPBTN)->widget_data = this->sorter_names[this->stations.SortType()]; } ~CompanyStationsWindow() { - this->last_sorting = this->stations.GetListing(); + /* Save filter state. */ + this->filter.last_sorting = this->stations.GetListing(); + CompanyStationsWindow::initial_state = this->filter; } void UpdateWidgetSize(int widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override @@ -397,8 +412,8 @@ public: case WID_STL_SORTDROPBTN: { Dimension d = {0, 0}; - for (int i = 0; this->sorter_names[i] != INVALID_STRING_ID; i++) { - d = maxdim(d, GetStringBoundingBox(this->sorter_names[i])); + for (int i = 0; CompanyStationsWindow::sorter_names[i] != INVALID_STRING_ID; i++) { + d = maxdim(d, GetStringBoundingBox(CompanyStationsWindow::sorter_names[i])); } d.width += padding.width; d.height += padding.height; @@ -502,7 +517,7 @@ public: if (widget >= WID_STL_CARGOSTART) { Rect br = r.Shrink(WidgetDimensions::scaled.bevel); const CargoSpec *cs = _sorted_cargo_specs[widget - WID_STL_CARGOSTART]; - int cg_ofst = HasBit(this->cargo_filter, cs->Index()) ? WidgetDimensions::scaled.pressed : 0; + int cg_ofst = HasBit(this->filter.cargoes, cs->Index()) ? WidgetDimensions::scaled.pressed : 0; br = br.Translate(cg_ofst, cg_ofst); GfxFillRect(br, cs->rating_colour); TextColour tc = GetContrastColour(cs->rating_colour); @@ -545,13 +560,13 @@ public: case WID_STL_AIRPLANE: case WID_STL_SHIP: if (_ctrl_pressed) { - ToggleBit(this->facilities, widget - WID_STL_TRAIN); + ToggleBit(this->filter.facilities, widget - WID_STL_TRAIN); this->ToggleWidgetLoweredState(widget); } else { - for (uint i : SetBitIterator(this->facilities)) { + for (uint i : SetBitIterator(this->filter.facilities)) { this->RaiseWidget(i + WID_STL_TRAIN); } - this->facilities = 1 << (widget - WID_STL_TRAIN); + this->filter.facilities = 1 << (widget - WID_STL_TRAIN); this->LowerWidget(widget); } this->stations.ForceRebuild(); @@ -563,7 +578,7 @@ public: this->LowerWidget(i); } - this->facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK; + this->filter.facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK; this->stations.ForceRebuild(); this->SetDirty(); break; @@ -574,8 +589,8 @@ public: } this->LowerWidget(WID_STL_NOCARGOWAITING); - this->cargo_filter = _cargo_mask; - this->include_empty = true; + this->filter.cargoes = _cargo_mask; + this->filter.include_empty = true; this->stations.ForceRebuild(); this->SetDirty(); break; @@ -592,15 +607,15 @@ public: case WID_STL_NOCARGOWAITING: if (_ctrl_pressed) { - this->include_empty = !this->include_empty; + this->filter.include_empty = !this->filter.include_empty; this->ToggleWidgetLoweredState(WID_STL_NOCARGOWAITING); } else { for (uint i = 0; i < _sorted_standard_cargo_specs.size(); i++) { this->RaiseWidget(WID_STL_CARGOSTART + i); } - this->cargo_filter = 0; - this->include_empty = true; + this->filter.cargoes = 0; + this->filter.include_empty = true; this->LowerWidget(WID_STL_NOCARGOWAITING); } @@ -614,7 +629,7 @@ public: const CargoSpec *cs = _sorted_cargo_specs[widget - WID_STL_CARGOSTART]; if (_ctrl_pressed) { - ToggleBit(this->cargo_filter, cs->Index()); + ToggleBit(this->filter.cargoes, cs->Index()); this->ToggleWidgetLoweredState(widget); } else { for (uint i = 0; i < _sorted_standard_cargo_specs.size(); i++) { @@ -622,10 +637,10 @@ public: } this->RaiseWidget(WID_STL_NOCARGOWAITING); - this->cargo_filter = 0; - this->include_empty = false; + this->filter.cargoes = 0; + this->filter.include_empty = false; - SetBit(this->cargo_filter, cs->Index()); + SetBit(this->filter.cargoes, cs->Index()); this->LowerWidget(widget); } this->stations.ForceRebuild(); @@ -642,7 +657,7 @@ public: this->stations.SetSortType(index); /* Display the current sort variant */ - this->GetWidget(WID_STL_SORTDROPBTN)->widget_data = this->sorter_names[this->stations.SortType()]; + this->GetWidget(WID_STL_SORTDROPBTN)->widget_data = CompanyStationsWindow::sorter_names[this->stations.SortType()]; this->SetDirty(); } @@ -678,12 +693,6 @@ public: } }; -Listing CompanyStationsWindow::last_sorting = {false, 0}; -byte CompanyStationsWindow::facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK; -bool CompanyStationsWindow::include_empty = true; -const CargoTypes CompanyStationsWindow::cargo_filter_max = ALL_CARGOTYPES; -CargoTypes CompanyStationsWindow::cargo_filter = ALL_CARGOTYPES; - /* Available station sorting functions */ GUIStationList::SortFunction * const CompanyStationsWindow::sorter_funcs[] = { &StationNameSorter,