From fe855b8474e6a7f99a864c06b9bc9e79f1546ab7 Mon Sep 17 00:00:00 2001 From: dP Date: Sat, 4 Mar 2023 20:10:40 +0400 Subject: [PATCH] Feature: Show the number of hidden vehicles on the button --- src/autoreplace_gui.cpp | 20 +++++++- src/build_vehicle_gui.cpp | 103 +++++++++++++++++++++++--------------- src/lang/english.txt | 8 +-- 3 files changed, 84 insertions(+), 47 deletions(-) diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 64707259d3..b60564cacd 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -88,6 +88,7 @@ class ReplaceVehicleWindow : public Window { byte sort_criteria; ///< Criteria of sorting vehicles. bool descending_sort_order; ///< Order of sorting vehicles. bool show_hidden_engines; ///< Whether to show the hidden engines. + uint num_hidden_engines; ///< Number of currently hidden engines. RailType sel_railtype; ///< Type of rail tracks selected. #INVALID_RAILTYPE to show all. RoadType sel_roadtype; ///< Type of road selected. #INVALID_ROADTYPE to show all. Scrollbar *vscroll[2]; @@ -146,9 +147,9 @@ class ReplaceVehicleWindow : public Window { byte side = draw_left ? 0 : 1; GUIEngineList list; + this->num_hidden_engines = 0; for (const Engine *e : Engine::IterateType(type)) { - if (!draw_left && !this->show_hidden_engines && e->IsVariantHidden(_local_company)) continue; EngineID eid = e->index; switch (type) { case VEH_TRAIN: @@ -173,6 +174,10 @@ class ReplaceVehicleWindow : public Window { if (num_engines == 0 && EngineReplacementForCompany(Company::Get(_local_company), eid, this->sel_group) == INVALID_ENGINE) continue; } else { if (!CheckAutoreplaceValidity(this->sel_engine[0], eid, _local_company)) continue; + if (e->IsVariantHidden(_local_company)) { + this->num_hidden_engines++; + if (!this->show_hidden_engines) continue; + } } list.emplace_back(eid, e->info.variant_id, (side == 0) ? EngineDisplayFlags::None : e->display_flags, 0); @@ -454,6 +459,10 @@ public: case WID_RV_ROAD_TYPE_DROPDOWN: SetDParam(0, this->sel_roadtype == INVALID_ROADTYPE ? STR_REPLACE_ALL_ROADTYPE : GetRoadTypeInfo(this->sel_roadtype)->strings.replace_text); break; + + case WID_RV_SHOW_HIDDEN_ENGINES: + SetDParam(0, this->num_hidden_engines); + break; } } @@ -499,7 +508,14 @@ public: void OnPaint() override { - if (this->engines[0].NeedRebuild() || this->engines[1].NeedRebuild()) this->GenerateLists(); + if (this->engines[0].NeedRebuild() || this->engines[1].NeedRebuild()) { + auto old_num_hidden_engines = this->num_hidden_engines; + this->GenerateLists(); + if (old_num_hidden_engines != this->num_hidden_engines) { + this->ReInit(); + return; + } + } Company *c = Company::Get(_local_company); diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 02e86115e2..32d89b455c 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1126,6 +1126,7 @@ struct BuildVehicleWindow : Window { bool descending_sort_order; ///< Sort direction, @see _engine_sort_direction byte sort_criteria; ///< Current sort criterium. bool show_hidden_engines; ///< State of the 'show hidden engines' button. + uint num_hidden_engines; ///< Number of currently hidden engines. bool listview_mode; ///< If set, only display the available vehicles and do not show a 'build' button. EngineID sel_engine; ///< Currently selected engine, or #INVALID_ENGINE EngineID rename_engine; ///< Engine being renamed. @@ -1187,7 +1188,10 @@ struct BuildVehicleWindow : Window { this->descending_sort_order = _engine_sort_last_order[type]; this->show_hidden_engines = _engine_sort_show_hidden_engines[type]; + this->SetCargoFilterArray(); this->UpdateFilterByTile(); + this->eng_list.ForceRebuild(); + this->GenerateBuildList(); // Needs to be before FinishInitNested to calculate num_hidden_engines for SetStringParameters this->CreateNestedTree(); @@ -1225,9 +1229,6 @@ struct BuildVehicleWindow : Window { this->owner = (tile != INVALID_TILE) ? GetTileOwner(tile) : _local_company; - this->eng_list.ForceRebuild(); - this->GenerateBuildList(); // generate the list, since we need it in the next line - /* Select the first unshaded engine in the list as default when opening the window */ EngineID engine = INVALID_ENGINE; auto it = std::find_if(this->eng_list.begin(), this->eng_list.end(), [&](GUIEngineListItem &item){ return (item.flags & EngineDisplayFlags::Shaded) == EngineDisplayFlags::None; }); @@ -1316,20 +1317,16 @@ struct BuildVehicleWindow : Window { this->te.FillDefaultCapacities(e); } - void OnInit() override - { - this->SetCargoFilterArray(); - } - - /** Filter the engine list against the currently selected cargo filter */ - void FilterEngineList() + /** Filter the engine list against the currently selected cargo filter and return the EngineID of currently selected engine. */ + EngineID FilterEngineList() { this->eng_list.Filter(this->cargo_filter_criteria); if (0 == this->eng_list.size()) { // no engine passed through the filter, invalidate the previously selected engine - this->SelectEngine(INVALID_ENGINE); + return INVALID_ENGINE; } else if (std::find(this->eng_list.begin(), this->eng_list.end(), this->sel_engine) == this->eng_list.end()) { // previously selected engine didn't pass the filter, select the first engine of the list - this->SelectEngine(this->eng_list[0].engine_id); + return this->eng_list[0].engine_id; } + return INVALID_ENGINE; } /** Filter a single engine */ @@ -1358,11 +1355,12 @@ struct BuildVehicleWindow : Window { } /* Figure out what train EngineIDs to put in the list */ - void GenerateBuildTrainList(GUIEngineList &list) + EngineID GenerateBuildTrainList(GUIEngineList &list) { std::vector variants; EngineID sel_id = INVALID_ENGINE; size_t num_engines = 0; + this->num_hidden_engines = 0; list.clear(); @@ -1371,7 +1369,6 @@ struct BuildVehicleWindow : Window { * and if not, reset selection to INVALID_ENGINE. This could be the case * when engines become obsolete and are removed */ for (const Engine *e : Engine::IterateType(VEH_TRAIN)) { - if (!this->show_hidden_engines && e->IsVariantHidden(_local_company)) continue; EngineID eid = e->index; const RailVehicleInfo *rvi = &e->u.rail; @@ -1384,6 +1381,12 @@ struct BuildVehicleWindow : Window { /* Filter by name or NewGRF extra text */ if (!FilterByText(e)) continue; + /* Note: needs to be the last check to calculate the number correctly */ + if (e->IsVariantHidden(_local_company)) { + this->num_hidden_engines++; + if (!this->show_hidden_engines) continue; + } + list.emplace_back(eid, e->info.variant_id, e->display_flags, 0); if (rvi->railveh_type != RAILVEH_WAGON) num_engines++; @@ -1407,8 +1410,6 @@ struct BuildVehicleWindow : Window { } } - this->SelectEngine(sel_id); - /* invalidate cached values for name sorter - engine names could change */ _last_engine[0] = _last_engine[1] = INVALID_ENGINE; @@ -1422,17 +1423,17 @@ struct BuildVehicleWindow : Window { /* and finally sort wagons */ EngList_SortPartial(list, _engine_sort_functions[0][this->sort_criteria], num_engines, list.size() - num_engines); + + return sel_id; } /* Figure out what road vehicle EngineIDs to put in the list */ void GenerateBuildRoadVehList() { - EngineID sel_id = INVALID_ENGINE; - this->eng_list.clear(); + this->num_hidden_engines = 0; for (const Engine *e : Engine::IterateType(VEH_ROAD)) { - if (!this->show_hidden_engines && e->IsVariantHidden(_local_company)) continue; EngineID eid = e->index; if (!IsEngineBuildable(eid, VEH_ROAD, _local_company)) continue; if (this->filter.roadtype != INVALID_ROADTYPE && !HasPowerOnRoad(e->u.road.roadtype, this->filter.roadtype)) continue; @@ -1440,40 +1441,44 @@ struct BuildVehicleWindow : Window { /* Filter by name or NewGRF extra text */ if (!FilterByText(e)) continue; - this->eng_list.emplace_back(eid, e->info.variant_id, e->display_flags, 0); + /* Note: needs to be the last check to calculate the number correctly */ + if (e->IsVariantHidden(_local_company)) { + this->num_hidden_engines++; + if (!this->show_hidden_engines) continue; + } - if (eid == this->sel_engine) sel_id = eid; + this->eng_list.emplace_back(eid, e->info.variant_id, e->display_flags, 0); } - this->SelectEngine(sel_id); } /* Figure out what ship EngineIDs to put in the list */ void GenerateBuildShipList() { - EngineID sel_id = INVALID_ENGINE; this->eng_list.clear(); + this->num_hidden_engines = 0; for (const Engine *e : Engine::IterateType(VEH_SHIP)) { - if (!this->show_hidden_engines && e->IsVariantHidden(_local_company)) continue; EngineID eid = e->index; if (!IsEngineBuildable(eid, VEH_SHIP, _local_company)) continue; /* Filter by name or NewGRF extra text */ if (!FilterByText(e)) continue; - this->eng_list.emplace_back(eid, e->info.variant_id, e->display_flags, 0); + /* Note: needs to be the last check to calculate the number correctly */ + if (e->IsVariantHidden(_local_company)) { + this->num_hidden_engines++; + if (!this->show_hidden_engines) continue; + } - if (eid == this->sel_engine) sel_id = eid; + this->eng_list.emplace_back(eid, e->info.variant_id, e->display_flags, 0); } - this->SelectEngine(sel_id); } /* Figure out what aircraft EngineIDs to put in the list */ void GenerateBuildAircraftList() { - EngineID sel_id = INVALID_ENGINE; - this->eng_list.clear(); + this->num_hidden_engines = 0; const Station *st = this->listview_mode ? nullptr : Station::GetByTile(this->window_number); @@ -1482,7 +1487,6 @@ struct BuildVehicleWindow : Window { * and if not, reset selection to INVALID_ENGINE. This could be the case * when planes become obsolete and are removed */ for (const Engine *e : Engine::IterateType(VEH_AIRCRAFT)) { - if (!this->show_hidden_engines && e->IsVariantHidden(_local_company)) continue; EngineID eid = e->index; if (!IsEngineBuildable(eid, VEH_AIRCRAFT, _local_company)) continue; /* First VEH_END window_numbers are fake to allow a window open for all different types at once */ @@ -1491,18 +1495,20 @@ struct BuildVehicleWindow : Window { /* Filter by name or NewGRF extra text */ if (!FilterByText(e)) continue; + /* Note: needs to be the last check to calculate the number correctly */ + if (e->IsVariantHidden(_local_company)) { + this->num_hidden_engines++; + if (!this->show_hidden_engines) continue; + } + this->eng_list.emplace_back(eid, e->info.variant_id, e->display_flags, 0); - - if (eid == this->sel_engine) sel_id = eid; } - - this->SelectEngine(sel_id); } /* Generate the list of vehicles */ - void GenerateBuildList() + EngineID GenerateBuildList() { - if (!this->eng_list.NeedRebuild()) return; + if (!this->eng_list.NeedRebuild()) return this->sel_engine; /* Update filter type in case the road/railtype of the depot got converted */ this->UpdateFilterByTile(); @@ -1510,15 +1516,16 @@ struct BuildVehicleWindow : Window { this->eng_list.clear(); GUIEngineList list; + EngineID sel_id = INVALID_ENGINE; switch (this->vehicle_type) { default: NOT_REACHED(); case VEH_TRAIN: - this->GenerateBuildTrainList(list); + sel_id = this->GenerateBuildTrainList(list); AddChildren(list, INVALID_ENGINE, 0); this->eng_list.shrink_to_fit(); this->eng_list.RebuildDone(); - return; + return sel_id; case VEH_ROAD: this->GenerateBuildRoadVehList(); break; @@ -1530,7 +1537,7 @@ struct BuildVehicleWindow : Window { break; } - this->FilterEngineList(); + sel_id = this->FilterEngineList(); /* ensure primary engine of variant group is in list after filtering */ std::vector variants; @@ -1556,6 +1563,8 @@ struct BuildVehicleWindow : Window { AddChildren(list, INVALID_ENGINE, 0); this->eng_list.shrink_to_fit(); this->eng_list.RebuildDone(); + + return sel_id; } DropDownList BuildCargoDropDownList() const @@ -1735,6 +1744,10 @@ struct BuildVehicleWindow : Window { } break; } + + case WID_BV_SHOW_HIDDEN_ENGINES: + SetDParam(0, this->num_hidden_engines); + break; } } @@ -1803,8 +1816,16 @@ struct BuildVehicleWindow : Window { void OnPaint() override { - this->GenerateBuildList(); - this->vscroll->SetCount(this->eng_list.size()); + uint old_num_hidden_engines = this->num_hidden_engines; + EngineID sel_id = this->GenerateBuildList(); + if (sel_id != this->sel_engine) this->SelectEngine(sel_id); + if (old_num_hidden_engines != this->num_hidden_engines) { + this->ReInit(); + return; + } + + this->vscroll->SetCount( + this->eng_list.size()); this->SetWidgetsDisabledState(this->sel_engine == INVALID_ENGINE, WID_BV_SHOW_HIDE, WID_BV_BUILD); diff --git a/src/lang/english.txt b/src/lang/english.txt index fa7aabb881..ac530cf6c2 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -294,10 +294,10 @@ STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC :{BLACK}Demolish # Show engines button ###length VEHICLE_TYPES -STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN :{BLACK}Show hidden -STR_SHOW_HIDDEN_ENGINES_VEHICLE_ROAD_VEHICLE :{BLACK}Show hidden -STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP :{BLACK}Show hidden -STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT :{BLACK}Show hidden +STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN :{BLACK}Show hidden ({NUM}) +STR_SHOW_HIDDEN_ENGINES_VEHICLE_ROAD_VEHICLE :{BLACK}Show hidden ({NUM}) +STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP :{BLACK}Show hidden ({NUM}) +STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT :{BLACK}Show hidden ({NUM}) ###length VEHICLE_TYPES STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP :{BLACK}By enabling this button, the hidden train vehicles are also displayed