|
|
|
@ -221,7 +221,7 @@ protected:
|
|
|
|
|
struct FilterState {
|
|
|
|
|
Listing last_sorting;
|
|
|
|
|
byte facilities; ///< types of stations of interest
|
|
|
|
|
bool include_empty; ///< whether we should include stations without waiting cargo
|
|
|
|
|
bool include_no_rating; ///< Whether we should include stations with no cargo rating.
|
|
|
|
|
CargoTypes cargoes; ///< bitmap of cargo types to include
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -257,18 +257,18 @@ protected:
|
|
|
|
|
for (const Station *st : Station::Iterate()) {
|
|
|
|
|
if (st->owner == owner || (st->owner == OWNER_NONE && HasStationInUse(st->index, true, owner))) {
|
|
|
|
|
if (this->filter.facilities & st->facilities) { // only stations with selected facilities
|
|
|
|
|
int num_waiting_cargo = 0;
|
|
|
|
|
bool has_rating = false;
|
|
|
|
|
for (CargoID j = 0; j < NUM_CARGO; j++) {
|
|
|
|
|
if (st->goods[j].HasRating()) {
|
|
|
|
|
num_waiting_cargo++; // count number of waiting cargo
|
|
|
|
|
has_rating = true;
|
|
|
|
|
if (HasBit(this->filter.cargoes, j)) {
|
|
|
|
|
this->stations.push_back(st);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* stations without waiting cargo */
|
|
|
|
|
if (num_waiting_cargo == 0 && this->filter.include_empty) {
|
|
|
|
|
/* Stations with no cargo rating. */
|
|
|
|
|
if (!has_rating && this->filter.include_no_rating) {
|
|
|
|
|
this->stations.push_back(st);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -374,20 +374,11 @@ public:
|
|
|
|
|
this->FinishInitNested(window_number);
|
|
|
|
|
this->owner = (Owner)this->window_number;
|
|
|
|
|
|
|
|
|
|
uint8_t index = 0;
|
|
|
|
|
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
|
|
|
|
|
if (HasBit(this->filter.cargoes, cs->Index())) {
|
|
|
|
|
this->LowerWidget(WID_STL_CARGOSTART + index);
|
|
|
|
|
}
|
|
|
|
|
index++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this->filter.cargoes == ALL_CARGOTYPES) this->filter.cargoes = _cargo_mask;
|
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < 5; i++) {
|
|
|
|
|
if (HasBit(this->filter.facilities, i)) this->LowerWidget(i + WID_STL_TRAIN);
|
|
|
|
|
}
|
|
|
|
|
this->SetWidgetLoweredState(WID_STL_NOCARGOWAITING, this->filter.include_empty);
|
|
|
|
|
|
|
|
|
|
this->GetWidget<NWidgetCore>(WID_STL_SORTDROPBTN)->widget_data = this->sorter_names[this->stations.SortType()];
|
|
|
|
|
}
|
|
|
|
@ -433,15 +424,6 @@ public:
|
|
|
|
|
/* Approximately match original 16 pixel wide rating bars by multiplying string width by 1.6 */
|
|
|
|
|
this->rating_width = this->rating_width * 16 / 10;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
if (widget >= WID_STL_CARGOSTART) {
|
|
|
|
|
Dimension d = GetStringBoundingBox(_sorted_cargo_specs[widget - WID_STL_CARGOSTART]->abbrev, FS_SMALL);
|
|
|
|
|
d.width += padding.width + 2;
|
|
|
|
|
d.height += padding.height;
|
|
|
|
|
*size = maxdim(*size, d);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -512,16 +494,6 @@ public:
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
if (widget >= WID_STL_CARGOSTART) {
|
|
|
|
|
Rect br = r.Shrink(WidgetDimensions::scaled.bevel);
|
|
|
|
|
const CargoSpec *cs = _sorted_cargo_specs[widget - WID_STL_CARGOSTART];
|
|
|
|
|
GfxFillRect(br, cs->rating_colour);
|
|
|
|
|
TextColour tc = GetContrastColour(cs->rating_colour);
|
|
|
|
|
DrawString(br.left, br.right, CenterBounds(br.top, br.bottom, GetCharacterHeight(FS_SMALL)), cs->abbrev, tc, SA_HOR_CENTER, false, FS_SMALL);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -531,6 +503,34 @@ public:
|
|
|
|
|
SetDParam(0, this->window_number);
|
|
|
|
|
SetDParam(1, this->vscroll->GetCount());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (widget == WID_STL_CARGODROPDOWN) {
|
|
|
|
|
if (this->filter.cargoes == 0) {
|
|
|
|
|
SetDParam(0, this->filter.include_no_rating ? STR_STATION_LIST_CARGO_FILTER_ONLY_NO_RATING : STR_STATION_LIST_CARGO_FILTER_NO_CARGO_TYPES);
|
|
|
|
|
} else if (this->filter.cargoes == _cargo_mask) {
|
|
|
|
|
SetDParam(0, this->filter.include_no_rating ? STR_STATION_LIST_CARGO_FILTER_ALL_AND_NO_RATING : STR_CARGO_TYPE_FILTER_ALL);
|
|
|
|
|
} else if (CountBits(this->filter.cargoes) == 1 && !this->filter.include_no_rating) {
|
|
|
|
|
SetDParam(0, CargoSpec::Get(FindFirstBit(this->filter.cargoes))->name);
|
|
|
|
|
} else {
|
|
|
|
|
SetDParam(0, STR_STATION_LIST_CARGO_FILTER_MULTIPLE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DropDownList BuildCargoDropDownList() const
|
|
|
|
|
{
|
|
|
|
|
/* Define a custom item consisting of check mark, icon and string. */
|
|
|
|
|
using DropDownListCargoItem = DropDownCheck<DropDownListIconItem>;
|
|
|
|
|
|
|
|
|
|
DropDownList list;
|
|
|
|
|
list.push_back(std::make_unique<DropDownListStringItem>(STR_STATION_LIST_CARGO_FILTER_SELECT_ALL, CargoFilterCriteria::CF_SELECT_ALL));
|
|
|
|
|
list.push_back(std::make_unique<DropDownListDividerItem>(-1));
|
|
|
|
|
list.push_back(std::make_unique<DropDownListCheckedItem>(this->filter.include_no_rating, STR_STATION_LIST_CARGO_FILTER_NO_RATING, CargoFilterCriteria::CF_NO_RATING));
|
|
|
|
|
for (const CargoSpec *cs : _sorted_cargo_specs) {
|
|
|
|
|
list.push_back(std::make_unique<DropDownListCargoItem>(HasBit(this->filter.cargoes, cs->Index()), cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
|
|
|
|
@ -581,19 +581,6 @@ public:
|
|
|
|
|
this->SetDirty();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case WID_STL_CARGOALL: {
|
|
|
|
|
for (uint i = 0; i < _sorted_standard_cargo_specs.size(); i++) {
|
|
|
|
|
this->LowerWidget(WID_STL_CARGOSTART + i);
|
|
|
|
|
}
|
|
|
|
|
this->LowerWidget(WID_STL_NOCARGOWAITING);
|
|
|
|
|
|
|
|
|
|
this->filter.cargoes = _cargo_mask;
|
|
|
|
|
this->filter.include_empty = true;
|
|
|
|
|
this->stations.ForceRebuild();
|
|
|
|
|
this->SetDirty();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case WID_STL_SORTBY: // flip sorting method asc/desc
|
|
|
|
|
this->stations.ToggleSortOrder();
|
|
|
|
|
this->SetDirty();
|
|
|
|
@ -603,62 +590,58 @@ public:
|
|
|
|
|
ShowDropDownMenu(this, this->sorter_names, this->stations.SortType(), WID_STL_SORTDROPBTN, 0, 0);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case WID_STL_NOCARGOWAITING:
|
|
|
|
|
if (_ctrl_pressed) {
|
|
|
|
|
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->filter.cargoes = 0;
|
|
|
|
|
this->filter.include_empty = true;
|
|
|
|
|
|
|
|
|
|
this->LowerWidget(WID_STL_NOCARGOWAITING);
|
|
|
|
|
}
|
|
|
|
|
this->stations.ForceRebuild();
|
|
|
|
|
this->SetDirty();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
if (widget >= WID_STL_CARGOSTART) { // change cargo_filter
|
|
|
|
|
/* Determine the selected cargo type */
|
|
|
|
|
const CargoSpec *cs = _sorted_cargo_specs[widget - WID_STL_CARGOSTART];
|
|
|
|
|
|
|
|
|
|
if (_ctrl_pressed) {
|
|
|
|
|
ToggleBit(this->filter.cargoes, cs->Index());
|
|
|
|
|
this->ToggleWidgetLoweredState(widget);
|
|
|
|
|
} else {
|
|
|
|
|
for (uint i = 0; i < _sorted_standard_cargo_specs.size(); i++) {
|
|
|
|
|
this->RaiseWidget(WID_STL_CARGOSTART + i);
|
|
|
|
|
}
|
|
|
|
|
this->RaiseWidget(WID_STL_NOCARGOWAITING);
|
|
|
|
|
|
|
|
|
|
this->filter.cargoes = 0;
|
|
|
|
|
this->filter.include_empty = false;
|
|
|
|
|
|
|
|
|
|
SetBit(this->filter.cargoes, cs->Index());
|
|
|
|
|
this->LowerWidget(widget);
|
|
|
|
|
}
|
|
|
|
|
this->stations.ForceRebuild();
|
|
|
|
|
this->SetDirty();
|
|
|
|
|
}
|
|
|
|
|
case WID_STL_CARGODROPDOWN:
|
|
|
|
|
/* Multiple-choice list should not have a default row selected, so use a non-present value. */
|
|
|
|
|
ShowDropDownList(this, this->BuildCargoDropDownList(), -1, widget, 0, false, true);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnDropdownSelect(WidgetID widget, int index) override
|
|
|
|
|
void OnDropdownSelect(int widget, int index) override
|
|
|
|
|
{
|
|
|
|
|
if (widget == WID_STL_SORTDROPBTN) {
|
|
|
|
|
if (this->stations.SortType() != index) {
|
|
|
|
|
this->stations.SetSortType(index);
|
|
|
|
|
|
|
|
|
|
/* Display the current sort variant */
|
|
|
|
|
this->GetWidget<NWidgetCore>(WID_STL_SORTDROPBTN)->widget_data = CompanyStationsWindow::sorter_names[this->stations.SortType()];
|
|
|
|
|
this->GetWidget<NWidgetCore>(WID_STL_SORTDROPBTN)->widget_data = this->sorter_names[this->stations.SortType()];
|
|
|
|
|
|
|
|
|
|
this->SetDirty();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (widget == WID_STL_CARGODROPDOWN) {
|
|
|
|
|
FilterState oldstate = this->filter;
|
|
|
|
|
|
|
|
|
|
if (index >= 0 && index < NUM_CARGO) {
|
|
|
|
|
if (_ctrl_pressed) {
|
|
|
|
|
ToggleBit(this->filter.cargoes, index);
|
|
|
|
|
} else {
|
|
|
|
|
this->filter.cargoes = 1ULL << index;
|
|
|
|
|
this->filter.include_no_rating = false;
|
|
|
|
|
}
|
|
|
|
|
} else if (index == CargoFilterCriteria::CF_NO_RATING) {
|
|
|
|
|
if (_ctrl_pressed) {
|
|
|
|
|
this->filter.include_no_rating = !this->filter.include_no_rating;
|
|
|
|
|
} else {
|
|
|
|
|
this->filter.include_no_rating = true;
|
|
|
|
|
this->filter.cargoes = 0;
|
|
|
|
|
}
|
|
|
|
|
} else if (index == CargoFilterCriteria::CF_SELECT_ALL) {
|
|
|
|
|
this->filter.cargoes = _cargo_mask;
|
|
|
|
|
this->filter.include_no_rating = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (oldstate.cargoes != this->filter.cargoes || oldstate.include_no_rating != this->filter.include_no_rating) {
|
|
|
|
|
this->stations.ForceRebuild();
|
|
|
|
|
this->SetDirty();
|
|
|
|
|
|
|
|
|
|
/* Only refresh the list if it's changed. */
|
|
|
|
|
if (_ctrl_pressed) ReplaceDropDownList(this, this->BuildCargoDropDownList());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Always close the list if ctrl is not pressed. */
|
|
|
|
|
if (!_ctrl_pressed) this->CloseChildWindows(WC_DROPDOWN_MENU);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -712,26 +695,6 @@ const StringID CompanyStationsWindow::sorter_names[] = {
|
|
|
|
|
INVALID_STRING_ID
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Make a horizontal row of cargo buttons, starting at widget #WID_STL_CARGOSTART.
|
|
|
|
|
* @return Horizontal row.
|
|
|
|
|
*/
|
|
|
|
|
static std::unique_ptr<NWidgetBase> CargoWidgets()
|
|
|
|
|
{
|
|
|
|
|
auto container = std::make_unique<NWidgetHorizontal>();
|
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < _sorted_standard_cargo_specs.size(); i++) {
|
|
|
|
|
auto panel = std::make_unique<NWidgetBackground>(WWT_PANEL, COLOUR_GREY, WID_STL_CARGOSTART + i);
|
|
|
|
|
panel->SetMinimalSize(14, 0);
|
|
|
|
|
panel->SetMinimalTextLines(1, 0, FS_NORMAL);
|
|
|
|
|
panel->SetResize(0, 0);
|
|
|
|
|
panel->SetFill(0, 1);
|
|
|
|
|
panel->SetDataTip(0, STR_STATION_LIST_USE_CTRL_TO_SELECT_MORE);
|
|
|
|
|
container->Add(std::move(panel));
|
|
|
|
|
}
|
|
|
|
|
return container;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static constexpr NWidgetPart _nested_company_stations_widgets[] = {
|
|
|
|
|
NWidget(NWID_HORIZONTAL),
|
|
|
|
|
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
|
|
|
|
@ -748,9 +711,7 @@ static constexpr NWidgetPart _nested_company_stations_widgets[] = {
|
|
|
|
|
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_STL_AIRPLANE), SetMinimalSize(14, 0), SetDataTip(STR_PLANE, STR_STATION_LIST_USE_CTRL_TO_SELECT_MORE), SetFill(0, 1),
|
|
|
|
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_STL_FACILALL), SetMinimalSize(14, 0), SetDataTip(STR_ABBREV_ALL, STR_STATION_LIST_SELECT_ALL_FACILITIES), SetTextStyle(TC_BLACK, FS_SMALL), SetFill(0, 1),
|
|
|
|
|
NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(5, 0), SetFill(0, 1), EndContainer(),
|
|
|
|
|
NWidgetFunction(CargoWidgets),
|
|
|
|
|
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_STL_NOCARGOWAITING), SetMinimalSize(14, 0), SetDataTip(STR_ABBREV_NONE, STR_STATION_LIST_NO_WAITING_CARGO), SetTextStyle(TC_BLACK, FS_SMALL), SetFill(0, 1),
|
|
|
|
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_STL_CARGOALL), SetMinimalSize(14, 0), SetDataTip(STR_ABBREV_ALL, STR_STATION_LIST_SELECT_ALL_TYPES), SetTextStyle(TC_BLACK, FS_SMALL), SetFill(0, 1),
|
|
|
|
|
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_STL_CARGODROPDOWN), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_STATION_LIST_USE_CTRL_TO_SELECT_MORE),
|
|
|
|
|
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(),
|
|
|
|
|
EndContainer(),
|
|
|
|
|
NWidget(NWID_HORIZONTAL),
|
|
|
|
|