diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index fd810c4ff6..f3da72a095 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1378,6 +1378,43 @@ struct BuildVehicleWindowBase : Window { DoCommandP(0, (1 << 23) | (1 << 21) | toadd->index, target, CMD_MOVE_VIRTUAL_RAIL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_MOVE_VEHICLE), CcMoveNewVirtualEngine); } } + + StringID GetCargoFilterLabel(CargoID cid) const + { + switch (cid) { + case CargoFilterCriteria::CF_ANY: return STR_PURCHASE_INFO_ALL_TYPES; + case CargoFilterCriteria::CF_ENGINES: return STR_PURCHASE_INFO_ENGINES_ONLY; + case CargoFilterCriteria::CF_NONE: return STR_PURCHASE_INFO_NONE; + default: return CargoSpec::Get(cid)->name; + } + } + + DropDownList BuildCargoDropDownList(bool hide_engines = false) const + { + DropDownList list; + + /* Add item for disabling filtering. */ + list.push_back(std::make_unique(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY, false)); + /* Specific filters for trains. */ + if (this->vehicle_type == VEH_TRAIN) { + if (!hide_engines) { + /* Add item for locomotives only in case of trains. */ + list.push_back(std::make_unique(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ENGINES), CargoFilterCriteria::CF_ENGINES, false)); + } + + /* Add item for vehicles not carrying anything, e.g. train engines. + * This could also be useful for eyecandy vehicles of other types, but is likely too confusing for joe, */ + list.push_back(std::make_unique(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE, false)); + } + + /* Add cargos */ + Dimension d = GetLargestCargoIconSize(); + for (const CargoSpec *cs : _sorted_standard_cargo_specs) { + list.push_back(std::make_unique(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false)); + } + + return list; + } }; /** GUI for building vehicles. */ @@ -1510,16 +1547,6 @@ struct BuildVehicleWindow : BuildVehicleWindowBase { } } - StringID GetCargoFilterLabel(CargoID cid) const - { - switch (cid) { - case CargoFilterCriteria::CF_ANY: return STR_PURCHASE_INFO_ALL_TYPES; - case CargoFilterCriteria::CF_ENGINES: return STR_PURCHASE_INFO_ENGINES_ONLY; - case CargoFilterCriteria::CF_NONE: return STR_PURCHASE_INFO_NONE; - default: return CargoSpec::Get(cid)->name; - } - } - /** Populate the filter list and set the cargo filter criteria. */ void SetCargoFilterArray() { @@ -1829,30 +1856,6 @@ struct BuildVehicleWindow : BuildVehicleWindowBase { this->eng_list.RebuildDone(); } - DropDownList BuildCargoDropDownList() const - { - DropDownList list; - - /* Add item for disabling filtering. */ - list.push_back(std::make_unique(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY, false)); - /* Specific filters for trains. */ - if (this->vehicle_type == VEH_TRAIN) { - /* Add item for locomotives only in case of trains. */ - list.push_back(std::make_unique(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ENGINES), CargoFilterCriteria::CF_ENGINES, false)); - /* Add item for vehicles not carrying anything, e.g. train engines. - * This could also be useful for eyecandy vehicles of other types, but is likely too confusing for joe, */ - list.push_back(std::make_unique(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE, false)); - } - - /* Add cargos */ - Dimension d = GetLargestCargoIconSize(); - for (const CargoSpec *cs : _sorted_standard_cargo_specs) { - list.push_back(std::make_unique(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false)); - } - - return list; - } - void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override { switch (widget) { @@ -2279,11 +2282,9 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { EngineID rename_engine {}; ///< Engine being renamed. GUIEngineList eng_list; Scrollbar *vscroll; - byte cargo_filter_criteria {}; ///< Selected cargo filter + CargoID cargo_filter_criteria; ///< Selected cargo filter bool show_hidden; ///< State of the 'show hidden' button. int details_height; ///< Minimal needed height of the details panels (found so far). - CargoID cargo_filter[NUM_CARGO + 2] {}; ///< Available cargo filters; CargoID or CF_ANY or CF_NONE - StringID cargo_filter_texts[NUM_CARGO + 3] {}; ///< Texts for filter_cargo, terminated by INVALID_STRING_ID TestedEngineDetails te; ///< Tested cost and capacity after refit. StringFilter string_filter; ///< Filter for vehicle name QueryString vehicle_editbox { MAX_LENGTH_VEHICLE_NAME_CHARS * MAX_CHAR_LENGTH, MAX_LENGTH_VEHICLE_NAME_CHARS }; ///< Filter editbox @@ -2296,9 +2297,8 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { bool GetRefitButtonMode(const PanelState &state) const { - bool refit = state.sel_engine != INVALID_ENGINE && state.cargo_filter[state.cargo_filter_criteria] != CargoFilterCriteria::CF_ANY && - state.cargo_filter[state.cargo_filter_criteria] != CargoFilterCriteria::CF_NONE; - if (refit) refit = Engine::Get(state.sel_engine)->GetDefaultCargoType() != state.cargo_filter[state.cargo_filter_criteria]; + bool refit = state.sel_engine != INVALID_ENGINE && state.cargo_filter_criteria != CargoFilterCriteria::CF_ANY && state.cargo_filter_criteria != CargoFilterCriteria::CF_NONE && state.cargo_filter_criteria != CargoFilterCriteria::CF_ENGINES; + if (refit) refit = Engine::Get(state.sel_engine)->GetDefaultCargoType() != state.cargo_filter_criteria; return refit; } @@ -2449,41 +2449,12 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { /** Populate the filter list and set the cargo filter criteria. */ void SetCargoFilterArray(PanelState &state, const CargoID last_filter) { - uint filter_items = 0; - - /* Add item for disabling filtering. */ - state.cargo_filter[filter_items] = CargoFilterCriteria::CF_ANY; - state.cargo_filter_texts[filter_items] = STR_PURCHASE_INFO_ALL_TYPES; - filter_items++; - - /* Add item for vehicles not carrying anything, e.g. train engines. */ - state.cargo_filter[filter_items] = CargoFilterCriteria::CF_NONE; - state.cargo_filter_texts[filter_items] = STR_PURCHASE_INFO_NONE; - filter_items++; - - /* Collect available cargo types for filtering. */ - for (const CargoSpec *cs : _sorted_standard_cargo_specs) { - state.cargo_filter[filter_items] = cs->Index(); - state.cargo_filter_texts[filter_items] = cs->name; - filter_items++; - } - - /* Terminate the filter list. */ - state.cargo_filter_texts[filter_items] = INVALID_STRING_ID; - - /* If not found, the cargo criteria will be set to all cargoes. */ - state.cargo_filter_criteria = 0; - - /* Find the last cargo filter criteria. */ - for (uint i = 0; i < filter_items; i++) { - if (state.cargo_filter[i] == last_filter) { - state.cargo_filter_criteria = i; - break; - } - } + /* Set the last cargo filter criteria. */ + state.cargo_filter_criteria = last_filter; + if (state.cargo_filter_criteria < NUM_CARGO && !HasBit(_standard_cargo_mask, state.cargo_filter_criteria)) state.cargo_filter_criteria = CargoFilterCriteria::CF_ANY; state.eng_list.SetFilterFuncs(_filter_funcs); - state.eng_list.SetFilterState(state.cargo_filter[state.cargo_filter_criteria] != CargoFilterCriteria::CF_ANY); + state.eng_list.SetFilterState(state.cargo_filter_criteria != CargoFilterCriteria::CF_ANY); } void SelectFirstEngine(PanelState &state) @@ -2496,7 +2467,7 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { void SelectEngine(PanelState &state, const EngineID engine) { - CargoID cargo = state.cargo_filter[state.cargo_filter_criteria]; + CargoID cargo = state.cargo_filter_criteria; if (cargo == CargoFilterCriteria::CF_ANY || cargo == CargoFilterCriteria::CF_ENGINES || cargo == CargoFilterCriteria::CF_NONE) cargo = INVALID_CARGO; state.sel_engine = engine; @@ -2580,9 +2551,8 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { /* Filter a single engine */ bool FilterSingleEngine(PanelState &state, EngineID eid) { - const CargoID filter_type = state.cargo_filter[state.cargo_filter_criteria]; GUIEngineListItem item = {eid, eid, EngineDisplayFlags::None, 0}; - return (filter_type == CargoFilterCriteria::CF_ANY || CargoAndEngineFilter(&item, filter_type)); + return state.cargo_filter_criteria == CargoFilterCriteria::CF_ANY || CargoAndEngineFilter(&item, state.cargo_filter_criteria); } /** Filter by name and NewGRF extra text */ @@ -2801,7 +2771,7 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { } case WID_BV_CARGO_FILTER_DROPDOWN_LOCO: { // Select cargo filtering criteria dropdown menu - ShowDropDownMenu(this, this->loco.cargo_filter_texts, this->loco.cargo_filter_criteria, WID_BV_CARGO_FILTER_DROPDOWN_LOCO, 0, 0); + ShowDropDownList(this, this->BuildCargoDropDownList(true), this->loco.cargo_filter_criteria, widget); break; } @@ -2814,7 +2784,7 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { } case WID_BV_BUILD_LOCO: { - this->BuildEngine(this->loco.sel_engine, this->loco.cargo_filter[this->loco.cargo_filter_criteria]); + this->BuildEngine(this->loco.sel_engine, this->loco.cargo_filter_criteria); break; } @@ -2865,7 +2835,7 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { } case WID_BV_CARGO_FILTER_DROPDOWN_WAGON: { // Select cargo filtering criteria dropdown menu - ShowDropDownMenu(this, this->wagon.cargo_filter_texts, this->wagon.cargo_filter_criteria, WID_BV_CARGO_FILTER_DROPDOWN_WAGON, 0, 0); + ShowDropDownList(this, this->BuildCargoDropDownList(true), this->wagon.cargo_filter_criteria, widget); break; } @@ -2878,7 +2848,7 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { } case WID_BV_BUILD_WAGON: { - this->BuildEngine(this->wagon.sel_engine, this->wagon.cargo_filter[this->wagon.cargo_filter_criteria]); + this->BuildEngine(this->wagon.sel_engine, this->wagon.cargo_filter_criteria); break; } @@ -2953,7 +2923,7 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { } case WID_BV_CARGO_FILTER_DROPDOWN_LOCO: { - SetDParam(0, this->loco.cargo_filter_texts[this->loco.cargo_filter_criteria]); + SetDParam(0, this->GetCargoFilterLabel(this->loco.cargo_filter_criteria)); break; } @@ -2963,7 +2933,7 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { } case WID_BV_CARGO_FILTER_DROPDOWN_WAGON: { - SetDParam(0, this->wagon.cargo_filter_texts[this->wagon.cargo_filter_criteria]); + SetDParam(0, this->GetCargoFilterLabel(this->wagon.cargo_filter_criteria)); break; } @@ -3157,9 +3127,9 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { case WID_BV_CARGO_FILTER_DROPDOWN_LOCO: { // Select a cargo filter criteria if (this->loco.cargo_filter_criteria != index) { this->loco.cargo_filter_criteria = static_cast(index); - _last_filter_criteria_loco = this->loco.cargo_filter[this->loco.cargo_filter_criteria]; + _last_filter_criteria_loco = this->loco.cargo_filter_criteria; /* deactivate filter if criteria is 'Show All', activate it otherwise */ - this->loco.eng_list.SetFilterState(this->loco.cargo_filter[this->loco.cargo_filter_criteria] != CargoFilterCriteria::CF_ANY); + this->loco.eng_list.SetFilterState(this->loco.cargo_filter_criteria != CargoFilterCriteria::CF_ANY); this->loco.eng_list.ForceRebuild(); } break; @@ -3177,9 +3147,9 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { case WID_BV_CARGO_FILTER_DROPDOWN_WAGON: { // Select a cargo filter criteria if (this->wagon.cargo_filter_criteria != index) { this->wagon.cargo_filter_criteria = static_cast(index); - _last_filter_criteria_wagon = this->wagon.cargo_filter[this->wagon.cargo_filter_criteria]; + _last_filter_criteria_wagon = this->wagon.cargo_filter_criteria; /* deactivate filter if criteria is 'Show All', activate it otherwise */ - this->wagon.eng_list.SetFilterState(this->wagon.cargo_filter[this->wagon.cargo_filter_criteria] != CargoFilterCriteria::CF_ANY); + this->wagon.eng_list.SetFilterState(this->wagon.cargo_filter_criteria != CargoFilterCriteria::CF_ANY); this->wagon.eng_list.ForceRebuild(); } break;