mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-08-20 21:19:10 +00:00
Compare commits
2 Commits
1242b355e5
...
7cfcf65f95
Author | SHA1 | Date | |
---|---|---|---|
7cfcf65f95 | |||
08dfe35442 |
@@ -1135,9 +1135,7 @@ struct BuildVehicleWindow : Window {
|
||||
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.
|
||||
@@ -1149,8 +1147,8 @@ struct BuildVehicleWindow : Window {
|
||||
{
|
||||
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 (refit) {
|
||||
widget->widget_data = STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON + this->vehicle_type;
|
||||
@@ -1272,58 +1270,29 @@ struct BuildVehicleWindow : Window {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -1359,7 +1328,7 @@ struct BuildVehicleWindow : Window {
|
||||
/** 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
|
||||
@@ -1370,9 +1339,8 @@ struct BuildVehicleWindow : Window {
|
||||
/** 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 */
|
||||
@@ -1594,6 +1562,29 @@ struct BuildVehicleWindow : Window {
|
||||
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) {
|
||||
@@ -1645,7 +1636,7 @@ struct BuildVehicleWindow : Window {
|
||||
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: {
|
||||
@@ -1659,7 +1650,7 @@ struct BuildVehicleWindow : Window {
|
||||
case WID_BV_BUILD: {
|
||||
EngineID sel_eng = this->sel_engine;
|
||||
if (sel_eng != INVALID_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;
|
||||
if (this->vehicle_type == VEH_TRAIN && RailVehInfo(sel_eng)->railveh_type == RAILVEH_WAGON) {
|
||||
Command<CMD_BUILD_VEHICLE>::Post(GetCmdBuildVehMsg(this->vehicle_type), CcBuildWagon, this->window_number, sel_eng, true, cargo, INVALID_CLIENT_ID);
|
||||
@@ -1735,7 +1726,7 @@ struct BuildVehicleWindow : Window {
|
||||
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: {
|
||||
@@ -1771,6 +1762,10 @@ struct BuildVehicleWindow : Window {
|
||||
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));
|
||||
@@ -1859,9 +1854,9 @@ struct BuildVehicleWindow : Window {
|
||||
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);
|
||||
}
|
||||
|
@@ -424,7 +424,7 @@ public:
|
||||
break;
|
||||
|
||||
case WID_GL_FILTER_BY_CARGO:
|
||||
size->width = GetStringListWidth(this->cargo_filter_texts) + padding.width;
|
||||
size->width = std::max(size->width, GetDropDownListDimension(this->BuildCargoDropDownList()).width + padding.width);
|
||||
break;
|
||||
|
||||
case WID_GL_MANAGE_VEHICLES_DROPDOWN: {
|
||||
@@ -470,7 +470,7 @@ public:
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_GL_FILTER_BY_CARGO:
|
||||
SetDParam(0, this->cargo_filter_texts[this->cargo_filter_criteria]);
|
||||
SetDParam(0, this->GetCargoFilterLabel(this->cargo_filter_criteria));
|
||||
break;
|
||||
|
||||
case WID_GL_AVAILABLE_VEHICLES:
|
||||
@@ -549,9 +549,6 @@ public:
|
||||
/* Set text of "sort by" dropdown widget. */
|
||||
this->GetWidget<NWidgetCore>(WID_GL_SORT_BY_DROPDOWN)->widget_data = this->GetVehicleSorterNames()[this->vehgroups.SortType()];
|
||||
|
||||
/* Set text of filter by cargo dropdown */
|
||||
this->GetWidget<NWidgetCore>(WID_GL_FILTER_BY_CARGO)->widget_data = this->cargo_filter_texts[this->cargo_filter_criteria];
|
||||
|
||||
this->DrawWidgets();
|
||||
}
|
||||
|
||||
@@ -668,7 +665,7 @@ public:
|
||||
return;
|
||||
|
||||
case WID_GL_FILTER_BY_CARGO: // Select filtering criteria dropdown menu
|
||||
ShowDropDownMenu(this, this->cargo_filter_texts, this->cargo_filter_criteria, WID_GL_FILTER_BY_CARGO, 0, 0);
|
||||
ShowDropDownList(this, this->BuildCargoDropDownList(), this->cargo_filter_criteria, widget);
|
||||
break;
|
||||
|
||||
case WID_GL_ALL_VEHICLES: // All vehicles button
|
||||
|
@@ -1319,10 +1319,8 @@ protected:
|
||||
Scrollbar *vscroll;
|
||||
Scrollbar *hscroll;
|
||||
|
||||
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
|
||||
byte produced_cargo_filter_criteria; ///< Selected produced cargo filter index
|
||||
byte accepted_cargo_filter_criteria; ///< Selected accepted cargo filter index
|
||||
CargoID produced_cargo_filter_criteria; ///< Selected produced cargo filter index
|
||||
CargoID accepted_cargo_filter_criteria; ///< Selected accepted cargo filter index
|
||||
static CargoID produced_cargo_filter;
|
||||
|
||||
const int MAX_FILTER_LENGTH = 16; ///< The max length of the filter, in chars
|
||||
@@ -1345,7 +1343,7 @@ protected:
|
||||
if (this->produced_cargo_filter_criteria != index) {
|
||||
this->produced_cargo_filter_criteria = index;
|
||||
/* deactivate filter if criteria is 'Show All', activate it otherwise */
|
||||
bool is_filtering_necessary = this->cargo_filter[this->produced_cargo_filter_criteria] != CF_ANY || this->cargo_filter[this->accepted_cargo_filter_criteria] != CF_ANY;
|
||||
bool is_filtering_necessary = this->produced_cargo_filter_criteria != CF_ANY || this->accepted_cargo_filter_criteria != CF_ANY;
|
||||
|
||||
this->industries.SetFilterState(is_filtering_necessary);
|
||||
this->industries.SetFilterType(0);
|
||||
@@ -1362,7 +1360,7 @@ protected:
|
||||
if (this->accepted_cargo_filter_criteria != index) {
|
||||
this->accepted_cargo_filter_criteria = index;
|
||||
/* deactivate filter if criteria is 'Show All', activate it otherwise */
|
||||
bool is_filtering_necessary = this->cargo_filter[this->produced_cargo_filter_criteria] != CF_ANY || this->cargo_filter[this->accepted_cargo_filter_criteria] != CF_ANY;
|
||||
bool is_filtering_necessary = this->produced_cargo_filter_criteria != CF_ANY || this->accepted_cargo_filter_criteria != CF_ANY;
|
||||
|
||||
this->industries.SetFilterState(is_filtering_necessary);
|
||||
this->industries.SetFilterType(0);
|
||||
@@ -1370,38 +1368,26 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
StringID GetCargoFilterLabel(CargoID cid) const
|
||||
{
|
||||
switch (cid) {
|
||||
case CF_ANY: return STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES;
|
||||
case CF_NONE: return STR_INDUSTRY_DIRECTORY_FILTER_NONE;
|
||||
default: return CargoSpec::Get(cid)->name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the filter list and set the cargo filter criteria.
|
||||
*/
|
||||
void SetCargoFilterArray()
|
||||
{
|
||||
byte filter_items = 0;
|
||||
|
||||
/* Add item for disabling filtering. */
|
||||
this->cargo_filter[filter_items] = CF_ANY;
|
||||
this->cargo_filter_texts[filter_items] = STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES;
|
||||
this->produced_cargo_filter_criteria = filter_items;
|
||||
this->accepted_cargo_filter_criteria = filter_items;
|
||||
filter_items++;
|
||||
|
||||
/* Add item for industries not producing anything, e.g. power plants */
|
||||
this->cargo_filter[filter_items] = CF_NONE;
|
||||
this->cargo_filter_texts[filter_items] = STR_INDUSTRY_DIRECTORY_FILTER_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;
|
||||
this->produced_cargo_filter_criteria = CF_ANY;
|
||||
this->accepted_cargo_filter_criteria = CF_ANY;
|
||||
|
||||
this->industries.SetFilterFuncs(_filter_funcs);
|
||||
|
||||
bool is_filtering_necessary = this->cargo_filter[this->produced_cargo_filter_criteria] != CF_ANY || this->cargo_filter[this->accepted_cargo_filter_criteria] != CF_ANY;
|
||||
bool is_filtering_necessary = this->produced_cargo_filter_criteria != CF_ANY || this->accepted_cargo_filter_criteria != CF_ANY;
|
||||
|
||||
this->industries.SetFilterState(is_filtering_necessary);
|
||||
}
|
||||
@@ -1438,8 +1424,7 @@ protected:
|
||||
this->industries.shrink_to_fit();
|
||||
this->industries.RebuildDone();
|
||||
|
||||
auto filter = std::make_pair(this->cargo_filter[this->accepted_cargo_filter_criteria],
|
||||
this->cargo_filter[this->produced_cargo_filter_criteria]);
|
||||
auto filter = std::make_pair(this->accepted_cargo_filter_criteria, this->produced_cargo_filter_criteria);
|
||||
|
||||
this->industries.Filter(filter);
|
||||
|
||||
@@ -1447,7 +1432,7 @@ protected:
|
||||
this->vscroll->SetCount(this->industries.size()); // Update scrollbar as well.
|
||||
}
|
||||
|
||||
IndustryDirectoryWindow::produced_cargo_filter = this->cargo_filter[this->produced_cargo_filter_criteria];
|
||||
IndustryDirectoryWindow::produced_cargo_filter = this->produced_cargo_filter_criteria;
|
||||
this->industries.Sort();
|
||||
|
||||
this->SetDirty();
|
||||
@@ -1599,7 +1584,7 @@ protected:
|
||||
|
||||
/* If the produced cargo filter is active then move the filtered cargo to the beginning of the list,
|
||||
* because this is the one the player interested in, and that way it is not hidden in the 'n' more cargos */
|
||||
const CargoID cid = this->cargo_filter[this->produced_cargo_filter_criteria];
|
||||
const CargoID cid = this->produced_cargo_filter_criteria;
|
||||
if (cid != CF_ANY && cid != CF_NONE) {
|
||||
auto filtered_ci = std::find_if(cargos.begin(), cargos.end(), [cid](const CargoInfo &ci) -> bool {
|
||||
return ci.cargo_id == cid;
|
||||
@@ -1669,11 +1654,11 @@ public:
|
||||
break;
|
||||
|
||||
case WID_ID_FILTER_BY_ACC_CARGO:
|
||||
SetDParam(0, this->cargo_filter_texts[this->accepted_cargo_filter_criteria]);
|
||||
SetDParam(0, this->GetCargoFilterLabel(this->accepted_cargo_filter_criteria));
|
||||
break;
|
||||
|
||||
case WID_ID_FILTER_BY_PROD_CARGO:
|
||||
SetDParam(0, this->cargo_filter_texts[this->produced_cargo_filter_criteria]);
|
||||
SetDParam(0, this->GetCargoFilterLabel(this->produced_cargo_filter_criteria));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1705,7 +1690,7 @@ public:
|
||||
break;
|
||||
}
|
||||
int n = 0;
|
||||
const CargoID acf_cid = this->cargo_filter[this->accepted_cargo_filter_criteria];
|
||||
const CargoID acf_cid = this->accepted_cargo_filter_criteria;
|
||||
for (uint i = this->vscroll->GetPosition(); i < this->industries.size(); i++) {
|
||||
TextColour tc = TC_FROMSTRING;
|
||||
if (acf_cid != CF_ANY && acf_cid != CF_NONE) {
|
||||
@@ -1758,6 +1743,22 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
DropDownList BuildCargoDropDownList() const
|
||||
{
|
||||
DropDownList list;
|
||||
|
||||
/* Add item for disabling filtering. */
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CF_ANY), CF_ANY, false));
|
||||
/* Add item for industries not producing anything, e.g. power plants */
|
||||
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
|
||||
{
|
||||
@@ -1772,11 +1773,11 @@ public:
|
||||
break;
|
||||
|
||||
case WID_ID_FILTER_BY_ACC_CARGO: // Cargo filter dropdown
|
||||
ShowDropDownMenu(this, this->cargo_filter_texts, this->accepted_cargo_filter_criteria, WID_ID_FILTER_BY_ACC_CARGO, 0, 0);
|
||||
ShowDropDownList(this, this->BuildCargoDropDownList(), this->accepted_cargo_filter_criteria, widget);
|
||||
break;
|
||||
|
||||
case WID_ID_FILTER_BY_PROD_CARGO: // Cargo filter dropdown
|
||||
ShowDropDownMenu(this, this->cargo_filter_texts, this->produced_cargo_filter_criteria, WID_ID_FILTER_BY_PROD_CARGO, 0, 0);
|
||||
ShowDropDownList(this, this->BuildCargoDropDownList(), this->produced_cargo_filter_criteria, widget);
|
||||
break;
|
||||
|
||||
case WID_ID_INDUSTRY_LIST: {
|
||||
|
@@ -300,7 +300,7 @@ void BaseVehicleListWindow::SetCargoFilterIndex(byte index)
|
||||
if (this->cargo_filter_criteria != index) {
|
||||
this->cargo_filter_criteria = index;
|
||||
/* Deactivate filter if criteria is 'Show All', activate it otherwise. */
|
||||
this->vehgroups.SetFilterState(this->cargo_filter[this->cargo_filter_criteria] != CF_ANY);
|
||||
this->vehgroups.SetFilterState(this->cargo_filter_criteria != CF_ANY);
|
||||
this->vehgroups.SetFilterType(0);
|
||||
this->vehgroups.ForceRebuild();
|
||||
}
|
||||
@@ -311,36 +311,9 @@ void BaseVehicleListWindow::SetCargoFilterIndex(byte index)
|
||||
*/
|
||||
void BaseVehicleListWindow::SetCargoFilterArray()
|
||||
{
|
||||
byte filter_items = 0;
|
||||
|
||||
/* Add item for disabling filtering. */
|
||||
this->cargo_filter[filter_items] = CF_ANY;
|
||||
this->cargo_filter_texts[filter_items] = STR_CARGO_TYPE_FILTER_ALL;
|
||||
this->cargo_filter_criteria = filter_items;
|
||||
filter_items++;
|
||||
|
||||
/* Add item for freight (i.e. vehicles with cargo capacity and with no passenger capacity). */
|
||||
this->cargo_filter[filter_items] = CF_FREIGHT;
|
||||
this->cargo_filter_texts[filter_items] = STR_CARGO_TYPE_FILTER_FREIGHT;
|
||||
filter_items++;
|
||||
|
||||
/* Add item for vehicles not carrying anything, e.g. train engines. */
|
||||
this->cargo_filter[filter_items] = CF_NONE;
|
||||
this->cargo_filter_texts[filter_items] = STR_CARGO_TYPE_FILTER_NONE;
|
||||
filter_items++;
|
||||
|
||||
/* Collect available cargo types for filtering. */
|
||||
for (const auto &cs : _sorted_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;
|
||||
|
||||
this->cargo_filter_criteria = CF_ANY;
|
||||
this->vehgroups.SetFilterFuncs(_filter_funcs);
|
||||
this->vehgroups.SetFilterState(this->cargo_filter[this->cargo_filter_criteria] != CF_ANY);
|
||||
this->vehgroups.SetFilterState(this->cargo_filter_criteria != CF_ANY);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -348,7 +321,7 @@ void BaseVehicleListWindow::SetCargoFilterArray()
|
||||
*/
|
||||
void BaseVehicleListWindow::FilterVehicleList()
|
||||
{
|
||||
this->vehgroups.Filter(this->cargo_filter[this->cargo_filter_criteria]);
|
||||
this->vehgroups.Filter(this->cargo_filter_criteria);
|
||||
if (this->vehicles.empty()) {
|
||||
/* No vehicle passed through the filter, invalidate the previously selected vehicle */
|
||||
this->vehicle_sel = INVALID_VEHICLE;
|
||||
@@ -388,6 +361,35 @@ void BaseVehicleListWindow::OnInit()
|
||||
this->SetCargoFilterArray();
|
||||
}
|
||||
|
||||
StringID BaseVehicleListWindow::GetCargoFilterLabel(CargoID cid) const
|
||||
{
|
||||
switch (cid) {
|
||||
case CF_ANY: return STR_CARGO_TYPE_FILTER_ALL;
|
||||
case CF_FREIGHT: return STR_CARGO_TYPE_FILTER_FREIGHT;
|
||||
case CF_NONE: return STR_CARGO_TYPE_FILTER_NONE;
|
||||
default: return CargoSpec::Get(cid)->name;
|
||||
}
|
||||
}
|
||||
|
||||
DropDownList BaseVehicleListWindow::BuildCargoDropDownList() const
|
||||
{
|
||||
DropDownList list;
|
||||
|
||||
/* Add item for disabling filtering. */
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CF_ANY), CF_ANY, false));
|
||||
/* Add item for freight (i.e. vehicles with cargo capacity and with no passenger capacity). */
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CF_FREIGHT), CF_FREIGHT, false));
|
||||
/* Add item for vehicles not carrying anything, e.g. train engines. */
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CF_NONE), CF_NONE, false));
|
||||
|
||||
/* Add cargos */
|
||||
for (const CargoSpec *cs : _sorted_cargo_specs) {
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(cs->name, cs->Index(), false));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the Action dropdown window.
|
||||
* @param show_autoreplace If true include the autoreplace item.
|
||||
@@ -1874,7 +1876,7 @@ public:
|
||||
break;
|
||||
|
||||
case WID_VL_FILTER_BY_CARGO:
|
||||
size->width = GetStringListWidth(this->cargo_filter_texts) + padding.width;
|
||||
size->width = std::max(size->width, GetDropDownListDimension(this->BuildCargoDropDownList()).width + padding.width);
|
||||
break;
|
||||
|
||||
case WID_VL_MANAGE_VEHICLES_DROPDOWN: {
|
||||
@@ -1895,7 +1897,7 @@ public:
|
||||
break;
|
||||
|
||||
case WID_VL_FILTER_BY_CARGO:
|
||||
SetDParam(0, this->cargo_filter_texts[this->cargo_filter_criteria]);
|
||||
SetDParam(0, this->GetCargoFilterLabel(this->cargo_filter_criteria));
|
||||
break;
|
||||
|
||||
case WID_VL_CAPTION:
|
||||
@@ -1975,7 +1977,7 @@ public:
|
||||
/* Set text of sort by dropdown widget. */
|
||||
this->GetWidget<NWidgetCore>(WID_VL_SORT_BY_PULLDOWN)->widget_data = this->GetVehicleSorterNames()[this->vehgroups.SortType()];
|
||||
|
||||
this->GetWidget<NWidgetCore>(WID_VL_FILTER_BY_CARGO)->widget_data = this->cargo_filter_texts[this->cargo_filter_criteria];
|
||||
this->GetWidget<NWidgetCore>(WID_VL_FILTER_BY_CARGO)->widget_data = this->GetCargoFilterLabel(this->cargo_filter_criteria);
|
||||
|
||||
this->DrawWidgets();
|
||||
}
|
||||
@@ -2004,7 +2006,7 @@ public:
|
||||
return;
|
||||
|
||||
case WID_VL_FILTER_BY_CARGO: // Cargo filter dropdown
|
||||
ShowDropDownMenu(this, this->cargo_filter_texts, this->cargo_filter_criteria, WID_VL_FILTER_BY_CARGO, 0, 0);
|
||||
ShowDropDownList(this, this->BuildCargoDropDownList(), this->cargo_filter_criteria, widget);
|
||||
break;
|
||||
|
||||
case WID_VL_LIST: { // Matrix to show vehicles
|
||||
|
@@ -88,8 +88,6 @@ struct BaseVehicleListWindow : public Window {
|
||||
Scrollbar *vscroll;
|
||||
VehicleListIdentifier vli; ///< Identifier of the vehicle list we want to currently show.
|
||||
VehicleID vehicle_sel; ///< Selected vehicle
|
||||
CargoID cargo_filter[NUM_CARGO + 3]; ///< Available cargo filters; CargoID or CF_ANY or CF_FREIGHT or CF_NONE
|
||||
StringID cargo_filter_texts[NUM_CARGO + 4]; ///< Texts for filter_cargo, terminated by INVALID_STRING_ID
|
||||
byte cargo_filter_criteria; ///< Selected cargo filter index
|
||||
uint order_arrow_width; ///< Width of the arrow in the small order list.
|
||||
|
||||
@@ -125,6 +123,8 @@ struct BaseVehicleListWindow : public Window {
|
||||
void SetCargoFilterIndex(byte index);
|
||||
void SetCargoFilterArray();
|
||||
void FilterVehicleList();
|
||||
StringID GetCargoFilterLabel(CargoID cid) const;
|
||||
DropDownList BuildCargoDropDownList() const;
|
||||
Dimension GetActionDropdownSize(bool show_autoreplace, bool show_group, bool show_create);
|
||||
DropDownList BuildActionDropdownList(bool show_autoreplace, bool show_group, bool show_create);
|
||||
|
||||
|
@@ -335,6 +335,21 @@ struct DropdownWindow : Window {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine width and height required to fully display a DropDownList
|
||||
* @param list The list.
|
||||
* @return Dimension required to display the list.
|
||||
*/
|
||||
Dimension GetDropDownListDimension(const DropDownList &list)
|
||||
{
|
||||
Dimension dim{};
|
||||
for (const auto &item : list) {
|
||||
dim.height += item->Height();
|
||||
dim.width = std::max(dim.width, item->Width());
|
||||
}
|
||||
return dim;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a drop down list.
|
||||
* @param w Parent window for the list.
|
||||
@@ -356,18 +371,9 @@ void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, int button
|
||||
/* The preferred width equals the calling widget */
|
||||
uint width = wi_rect.Width();
|
||||
|
||||
/* Longest item in the list */
|
||||
uint max_item_width = 0;
|
||||
|
||||
/* Total height of list */
|
||||
uint height = 0;
|
||||
|
||||
for (const auto &item : list) {
|
||||
height += item->Height();
|
||||
max_item_width = std::max(max_item_width, item->Width());
|
||||
}
|
||||
|
||||
max_item_width += WidgetDimensions::scaled.fullbevel.Horizontal();
|
||||
/* Get the height and width required for the list. */
|
||||
Dimension dim = GetDropDownListDimension(list);
|
||||
dim.width += WidgetDimensions::scaled.fullbevel.Horizontal();
|
||||
|
||||
/* Scrollbar needed? */
|
||||
bool scroll = false;
|
||||
@@ -379,7 +385,7 @@ void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, int button
|
||||
uint available_height = std::max(GetMainViewBottom() - top - (int)WidgetDimensions::scaled.fullbevel.Vertical() * 2, 0);
|
||||
|
||||
/* If the dropdown doesn't fully fit below the widget... */
|
||||
if (height > available_height) {
|
||||
if (dim.height > available_height) {
|
||||
|
||||
uint available_height_above = std::max(w->top + wi_rect.top - GetMainViewTop() - (int)WidgetDimensions::scaled.fullbevel.Vertical() * 2, 0);
|
||||
|
||||
@@ -390,29 +396,28 @@ void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, int button
|
||||
}
|
||||
|
||||
/* If the dropdown doesn't fully fit, we need a dropdown. */
|
||||
if (height > available_height) {
|
||||
if (dim.height > available_height) {
|
||||
scroll = true;
|
||||
uint avg_height = height / (uint)list.size();
|
||||
uint avg_height = dim.height / (uint)list.size();
|
||||
|
||||
/* Fit the list; create at least one row, even if there is no height available. */
|
||||
uint rows = std::max<uint>(available_height / avg_height, 1);
|
||||
height = rows * avg_height;
|
||||
dim.height = rows * avg_height;
|
||||
|
||||
/* Add space for the scrollbar. */
|
||||
max_item_width += NWidgetScrollbar::GetVerticalDimension().width;
|
||||
dim.width += NWidgetScrollbar::GetVerticalDimension().width;
|
||||
}
|
||||
|
||||
/* Set the top position if needed. */
|
||||
if (above) {
|
||||
top = w->top + wi_rect.top - height - WidgetDimensions::scaled.fullbevel.Vertical() * 2;
|
||||
top = w->top + wi_rect.top - dim.height - WidgetDimensions::scaled.fullbevel.Vertical() * 2;
|
||||
}
|
||||
}
|
||||
|
||||
width = std::max(width, max_item_width);
|
||||
dim.width = std::max(width, dim.width);
|
||||
|
||||
Point dw_pos = { w->left + (_current_text_dir == TD_RTL ? wi_rect.right + 1 - (int)width : wi_rect.left), top};
|
||||
Dimension dw_size = {width, height};
|
||||
DropdownWindow *dropdown = new DropdownWindow(w, std::move(list), selected, button, instant_close, dw_pos, dw_size, wi_colour, scroll);
|
||||
DropdownWindow *dropdown = new DropdownWindow(w, std::move(list), selected, button, instant_close, dw_pos, dim, wi_colour, scroll);
|
||||
|
||||
/* The dropdown starts scrolling downwards when opening it towards
|
||||
* the top and holding down the mouse button. It can be fooled by
|
||||
|
@@ -76,4 +76,6 @@ void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, int button
|
||||
|
||||
void ShowDropDownList(Window *w, DropDownList &&list, int selected, int button, uint width = 0, bool instant_close = false);
|
||||
|
||||
Dimension GetDropDownListDimension(const DropDownList &list);
|
||||
|
||||
#endif /* WIDGETS_DROPDOWN_TYPE_H */
|
||||
|
Reference in New Issue
Block a user