Merge branch 'master' into jgrpp

# Conflicts:
#	src/articulated_vehicles.cpp
#	src/articulated_vehicles.h
#	src/autoreplace_cmd.cpp
#	src/build_vehicle_gui.cpp
#	src/company_gui.cpp
#	src/core/format.hpp
#	src/genworld_gui.cpp
#	src/gfx.cpp
#	src/group_gui.cpp
#	src/linkgraph/linkgraph_gui.cpp
#	src/misc/endian_buffer.hpp
#	src/music/music_driver.hpp
#	src/newgrf_gui.cpp
#	src/rail_cmd.cpp
#	src/road_gui.cpp
#	src/settings_type.h
#	src/strgen/strgen.cpp
#	src/strings.cpp
#	src/timetable_cmd.cpp
#	src/town.h
#	src/vehicle.cpp
#	src/vehicle_gui.cpp
#	src/vehicle_gui_base.h
#	src/widget.cpp
#	src/widgets/dropdown.cpp
#	src/widgets/road_widget.h
This commit is contained in:
Jonathan G Rennison
2023-12-16 23:54:58 +00:00
130 changed files with 1765 additions and 1676 deletions

View File

@@ -1398,9 +1398,7 @@ struct BuildVehicleWindow : BuildVehicleWindowBase {
EngineID sel_engine; ///< Currently selected engine, or #INVALID_ENGINE
EngineID rename_engine; ///< Engine being renamed.
GUIEngineList eng_list;
CargoID cargo_filter[NUM_CARGO + 3]; ///< Available cargo filters; CargoID or CF_ANY or CF_NONE or CF_ENGINES
StringID cargo_filter_texts[NUM_CARGO + 4]; ///< Texts for filter_cargo, terminated by INVALID_STRING_ID
byte cargo_filter_criteria; ///< Selected cargo filter
CargoID cargo_filter_criteria; ///< Selected cargo filter
int details_height; ///< Minimal needed height of the details panels, in text lines (found so far).
Scrollbar *vscroll;
TestedEngineDetails te; ///< Tested cost and capacity after refit.
@@ -1412,8 +1410,8 @@ struct BuildVehicleWindow : BuildVehicleWindowBase {
{
NWidgetCore *widget = this->GetWidget<NWidgetCore>(WID_BV_BUILD);
bool refit = this->sel_engine != INVALID_ENGINE && this->cargo_filter[this->cargo_filter_criteria] != CF_ANY && this->cargo_filter[this->cargo_filter_criteria] != CF_NONE;
if (refit) refit = Engine::Get(this->sel_engine)->GetDefaultCargoType() != this->cargo_filter[this->cargo_filter_criteria];
bool refit = this->sel_engine != INVALID_ENGINE && this->cargo_filter_criteria != CF_ANY && this->cargo_filter_criteria != CF_NONE;
if (refit) refit = Engine::Get(this->sel_engine)->GetDefaultCargoType() != this->cargo_filter_criteria;
if (this->virtual_train_mode) {
if (refit) {
@@ -1518,58 +1516,29 @@ struct BuildVehicleWindow : BuildVehicleWindowBase {
}
}
StringID GetCargoFilterLabel(CargoID cid) const
{
switch (cid) {
case CF_ANY: return STR_PURCHASE_INFO_ALL_TYPES;
case CF_ENGINES: return STR_PURCHASE_INFO_ENGINES_ONLY;
case 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()
{
uint filter_items = 0;
/* Add item for disabling filtering. */
this->cargo_filter[filter_items] = CF_ANY;
this->cargo_filter_texts[filter_items] = STR_PURCHASE_INFO_ALL_TYPES;
filter_items++;
/* Specific filters for trains. */
if (this->vehicle_type == VEH_TRAIN) {
/* Add item for locomotives only in case of trains. */
this->cargo_filter[filter_items] = CF_ENGINES;
this->cargo_filter_texts[filter_items] = STR_PURCHASE_INFO_ENGINES_ONLY;
filter_items++;
/* 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, */
this->cargo_filter[filter_items] = CF_NONE;
this->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) {
this->cargo_filter[filter_items] = cs->Index();
this->cargo_filter_texts[filter_items] = cs->name;
filter_items++;
}
/* Terminate the filter list. */
this->cargo_filter_texts[filter_items] = INVALID_STRING_ID;
/* If not found, the cargo criteria will be set to all cargoes. */
this->cargo_filter_criteria = 0;
/* Find the last cargo filter criteria. */
for (uint i = 0; i < filter_items; i++) {
if (this->cargo_filter[i] == _engine_sort_last_cargo_criteria[this->vehicle_type]) {
this->cargo_filter_criteria = i;
break;
}
}
/* Set the last cargo filter criteria. */
this->cargo_filter_criteria = _engine_sort_last_cargo_criteria[this->vehicle_type];
this->eng_list.SetFilterFuncs(_filter_funcs);
this->eng_list.SetFilterState(this->cargo_filter[this->cargo_filter_criteria] != CF_ANY);
this->eng_list.SetFilterState(this->cargo_filter_criteria != CF_ANY);
}
void SelectEngine(EngineID engine)
{
CargoID cargo = this->cargo_filter[this->cargo_filter_criteria];
CargoID cargo = this->cargo_filter_criteria;
if (cargo == CF_ANY || cargo == CF_ENGINES || cargo == CF_NONE) cargo = CT_INVALID;
this->sel_engine = engine;
@@ -1631,7 +1600,7 @@ struct BuildVehicleWindow : BuildVehicleWindowBase {
/** Filter the engine list against the currently selected cargo filter */
void FilterEngineList()
{
this->eng_list.Filter(this->cargo_filter[this->cargo_filter_criteria]);
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);
} 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
@@ -1642,9 +1611,8 @@ struct BuildVehicleWindow : BuildVehicleWindowBase {
/** Filter a single engine */
bool FilterSingleEngine(EngineID eid)
{
CargoID filter_type = this->cargo_filter[this->cargo_filter_criteria];
GUIEngineListItem item = {eid, eid, EngineDisplayFlags::None, 0};
return CargoAndEngineFilter(&item, filter_type);
return CargoAndEngineFilter(&item, this->cargo_filter_criteria);
}
/** Filter by name and NewGRF extra text */
@@ -1866,6 +1834,29 @@ struct BuildVehicleWindow : BuildVehicleWindowBase {
this->eng_list.RebuildDone();
}
DropDownList BuildCargoDropDownList() const
{
DropDownList list;
/* Add item for disabling filtering. */
list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CF_ANY), 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<DropDownListStringItem>(this->GetCargoFilterLabel(CF_ENGINES), 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<DropDownListStringItem>(this->GetCargoFilterLabel(CF_NONE), CF_NONE, false));
}
/* Add cargos */
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
list.push_back(std::make_unique<DropDownListStringItem>(cs->name, cs->Index(), false));
}
return list;
}
void OnClick([[maybe_unused]] Point pt, int widget, [[maybe_unused]] int click_count) override
{
switch (widget) {
@@ -1918,7 +1909,7 @@ struct BuildVehicleWindow : BuildVehicleWindowBase {
break;
case WID_BV_CARGO_FILTER_DROPDOWN: // Select cargo filtering criteria dropdown menu
ShowDropDownMenu(this, this->cargo_filter_texts, this->cargo_filter_criteria, WID_BV_CARGO_FILTER_DROPDOWN, 0, 0);
ShowDropDownList(this, this->BuildCargoDropDownList(), this->cargo_filter_criteria, widget);
break;
case WID_BV_SHOW_HIDE: {
@@ -1942,7 +1933,7 @@ struct BuildVehicleWindow : BuildVehicleWindowBase {
? CcBuildWagon : CcBuildPrimaryVehicle;
cmd = GetCmdBuildVeh(this->vehicle_type);
}
CargoID cargo = this->cargo_filter[this->cargo_filter_criteria];
CargoID cargo = this->cargo_filter_criteria;
if (cargo == CF_ANY || cargo == CF_ENGINES || cargo == CF_NONE) cargo = CT_INVALID;
DoCommandP(this->window_number, sel_eng | (cargo << 24), 0, cmd, callback);
@@ -2015,7 +2006,7 @@ struct BuildVehicleWindow : BuildVehicleWindowBase {
break;
case WID_BV_CARGO_FILTER_DROPDOWN:
SetDParam(0, this->cargo_filter_texts[this->cargo_filter_criteria]);
SetDParam(0, this->GetCargoFilterLabel(this->cargo_filter_criteria));
break;
case WID_BV_SHOW_HIDE: {
@@ -2051,6 +2042,10 @@ struct BuildVehicleWindow : BuildVehicleWindowBase {
break;
}
case WID_BV_CARGO_FILTER_DROPDOWN:
size->width = std::max(size->width, GetDropDownListDimension(this->BuildCargoDropDownList()).width + padding.width);
break;
case WID_BV_BUILD:
*size = GetStringBoundingBox(STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON + this->vehicle_type);
*size = maxdim(*size, GetStringBoundingBox(STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON + this->vehicle_type));
@@ -2142,9 +2137,9 @@ struct BuildVehicleWindow : BuildVehicleWindowBase {
case WID_BV_CARGO_FILTER_DROPDOWN: // Select a cargo filter criteria
if (this->cargo_filter_criteria != index) {
this->cargo_filter_criteria = index;
_engine_sort_last_cargo_criteria[this->vehicle_type] = this->cargo_filter[this->cargo_filter_criteria];
_engine_sort_last_cargo_criteria[this->vehicle_type] = this->cargo_filter_criteria;
/* deactivate filter if criteria is 'Show All', activate it otherwise */
this->eng_list.SetFilterState(this->cargo_filter[this->cargo_filter_criteria] != CF_ANY);
this->eng_list.SetFilterState(this->cargo_filter_criteria != CF_ANY);
this->eng_list.ForceRebuild();
this->SelectEngine(this->sel_engine);
}