Merge remote-tracking branch 'upstream/master'

This commit is contained in:
dP
2025-05-14 18:41:13 +05:00
994 changed files with 38759 additions and 34518 deletions

View File

@@ -26,7 +26,8 @@
#include "vehicle_func.h"
#include "autoreplace_gui.h"
#include "string_func.h"
#include "widgets/dropdown_func.h"
#include "dropdown_type.h"
#include "dropdown_func.h"
#include "timetable.h"
#include "articulated_vehicles.h"
#include "spritecache.h"
@@ -81,7 +82,7 @@ static bool VehicleIndividualToGroupSorterWrapper(GUIVehicleGroup const &a, GUIV
return func(*(a.vehicles_begin), *(b.vehicles_begin));
}
BaseVehicleListWindow::VehicleGroupSortFunction * const BaseVehicleListWindow::vehicle_group_none_sorter_funcs[] = {
const std::initializer_list<BaseVehicleListWindow::VehicleGroupSortFunction * const> BaseVehicleListWindow::vehicle_group_none_sorter_funcs = {
&VehicleIndividualToGroupSorterWrapper<VehicleNumberSorter>,
&VehicleIndividualToGroupSorterWrapper<VehicleNameSorter>,
&VehicleIndividualToGroupSorterWrapper<VehicleAgeSorter>,
@@ -97,7 +98,7 @@ BaseVehicleListWindow::VehicleGroupSortFunction * const BaseVehicleListWindow::v
&VehicleIndividualToGroupSorterWrapper<VehicleTimetableDelaySorter>,
};
const StringID BaseVehicleListWindow::vehicle_group_none_sorter_names_calendar[] = {
const std::initializer_list<const StringID> BaseVehicleListWindow::vehicle_group_none_sorter_names_calendar = {
STR_SORT_BY_NUMBER,
STR_SORT_BY_NAME,
STR_SORT_BY_AGE,
@@ -111,10 +112,9 @@ const StringID BaseVehicleListWindow::vehicle_group_none_sorter_names_calendar[]
STR_SORT_BY_LENGTH,
STR_SORT_BY_LIFE_TIME,
STR_SORT_BY_TIMETABLE_DELAY,
INVALID_STRING_ID
};
const StringID BaseVehicleListWindow::vehicle_group_none_sorter_names_wallclock[] = {
const std::initializer_list<const StringID> BaseVehicleListWindow::vehicle_group_none_sorter_names_wallclock = {
STR_SORT_BY_NUMBER,
STR_SORT_BY_NAME,
STR_SORT_BY_AGE,
@@ -128,10 +128,9 @@ const StringID BaseVehicleListWindow::vehicle_group_none_sorter_names_wallclock[
STR_SORT_BY_LENGTH,
STR_SORT_BY_LIFE_TIME,
STR_SORT_BY_TIMETABLE_DELAY,
INVALID_STRING_ID
};
BaseVehicleListWindow::VehicleGroupSortFunction * const BaseVehicleListWindow::vehicle_group_shared_orders_sorter_funcs[] = {
const std::initializer_list<BaseVehicleListWindow::VehicleGroupSortFunction * const> BaseVehicleListWindow::vehicle_group_shared_orders_sorter_funcs = {
&VehicleGroupLengthSorter,
&VehicleGroupTotalProfitThisYearSorter,
&VehicleGroupTotalProfitLastYearSorter,
@@ -139,28 +138,25 @@ BaseVehicleListWindow::VehicleGroupSortFunction * const BaseVehicleListWindow::v
&VehicleGroupAverageProfitLastYearSorter,
};
const StringID BaseVehicleListWindow::vehicle_group_shared_orders_sorter_names_calendar[] = {
const std::initializer_list<const StringID> BaseVehicleListWindow::vehicle_group_shared_orders_sorter_names_calendar = {
STR_SORT_BY_NUM_VEHICLES,
STR_SORT_BY_TOTAL_PROFIT_THIS_YEAR,
STR_SORT_BY_TOTAL_PROFIT_LAST_YEAR,
STR_SORT_BY_AVERAGE_PROFIT_THIS_YEAR,
STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR,
INVALID_STRING_ID
};
const StringID BaseVehicleListWindow::vehicle_group_shared_orders_sorter_names_wallclock[] = {
const std::initializer_list<const StringID> BaseVehicleListWindow::vehicle_group_shared_orders_sorter_names_wallclock = {
STR_SORT_BY_NUM_VEHICLES,
STR_SORT_BY_TOTAL_PROFIT_THIS_PERIOD,
STR_SORT_BY_TOTAL_PROFIT_LAST_PERIOD,
STR_SORT_BY_AVERAGE_PROFIT_THIS_PERIOD,
STR_SORT_BY_AVERAGE_PROFIT_LAST_PERIOD,
INVALID_STRING_ID
};
const StringID BaseVehicleListWindow::vehicle_group_by_names[] = {
const std::initializer_list<const StringID> BaseVehicleListWindow::vehicle_group_by_names = {
STR_GROUP_BY_NONE,
STR_GROUP_BY_SHARED_ORDERS,
INVALID_STRING_ID
};
const StringID BaseVehicleListWindow::vehicle_depot_name[] = {
@@ -170,14 +166,14 @@ const StringID BaseVehicleListWindow::vehicle_depot_name[] = {
STR_VEHICLE_LIST_SEND_AIRCRAFT_TO_HANGAR
};
BaseVehicleListWindow::BaseVehicleListWindow(WindowDesc *desc, WindowNumber wno) : Window(desc), vli(VehicleListIdentifier::UnPack(wno))
BaseVehicleListWindow::BaseVehicleListWindow(WindowDesc &desc, WindowNumber wno) : Window(desc), vli(VehicleListIdentifier::UnPack(wno))
{
this->vehicle_sel = INVALID_VEHICLE;
this->grouping = _grouping[vli.type][vli.vtype];
this->UpdateSortingFromGrouping();
}
const StringID *BaseVehicleListWindow::GetVehicleSorterNames()
std::span<const StringID> BaseVehicleListWindow::GetVehicleSorterNames()
{
switch (this->grouping) {
case GB_NONE:
@@ -337,7 +333,83 @@ static bool CargoFilter(const GUIVehicleGroup *vehgroup, const CargoID cid)
return false;
}
static GUIVehicleGroupList::FilterFunction * const _filter_funcs[] = {
/**
* Test if cargo icon overlays should be drawn.
* @returns true iff cargo icon overlays should be drawn.
*/
bool ShowCargoIconOverlay()
{
return _shift_pressed && _ctrl_pressed;
}
/**
* Add a cargo icon to the list of overlays.
* @param overlays List of overlays.
* @param x Horizontal position.
* @param width Width available.
* @param v Vehicle to add.
*/
void AddCargoIconOverlay(std::vector<CargoIconOverlay> &overlays, int x, int width, const Vehicle *v)
{
bool rtl = _current_text_dir == TD_RTL;
if (!v->IsArticulatedPart() || v->cargo_type != v->Previous()->cargo_type) {
/* Add new overlay slot. */
overlays.emplace_back(rtl ? x - width : x, rtl ? x : x + width, v->cargo_type, v->cargo_cap);
} else {
/* This is an articulated part with the same cargo type, adjust left or right of last overlay slot. */
if (rtl) {
overlays.back().left -= width;
} else {
overlays.back().right += width;
}
overlays.back().cargo_cap += v->cargo_cap;
}
}
/**
* Draw a cargo icon overlaying an existing sprite, with a black contrast outline.
* @param x Horizontal position from left.
* @param y Vertical position from top.
* @param cid Cargo ID to draw icon for.
*/
void DrawCargoIconOverlay(int x, int y, CargoID cid)
{
if (!ShowCargoIconOverlay()) return;
if (!IsValidCargoID(cid)) return;
const CargoSpec *cs = CargoSpec::Get(cid);
SpriteID spr = cs->GetCargoIcon();
if (spr == 0) return;
Dimension d = GetSpriteSize(spr);
d.width /= 2;
d.height /= 2;
int one = ScaleGUITrad(1);
/* Draw the cargo icon in black shifted 4 times to create the outline. */
DrawSprite(spr, PALETTE_ALL_BLACK, x - d.width - one, y - d.height);
DrawSprite(spr, PALETTE_ALL_BLACK, x - d.width + one, y - d.height);
DrawSprite(spr, PALETTE_ALL_BLACK, x - d.width, y - d.height - one);
DrawSprite(spr, PALETTE_ALL_BLACK, x - d.width, y - d.height + one);
/* Draw the cargo icon normally. */
DrawSprite(spr, PAL_NONE, x - d.width, y - d.height);
}
/**
* Draw a list of cargo icon overlays.
* @param overlays List of overlays.
* @param y Vertical position.
*/
void DrawCargoIconOverlays(std::span<const CargoIconOverlay> overlays, int y)
{
for (const auto &cio : overlays) {
if (cio.cargo_cap == 0) continue;
DrawCargoIconOverlay((cio.left + cio.right) / 2, y, cio.cargo_type);
}
}
static GUIVehicleGroupList::FilterFunction * const _vehicle_group_filter_funcs[] = {
&CargoFilter,
};
@@ -362,7 +434,7 @@ void BaseVehicleListWindow::SetCargoFilter(CargoID cid)
void BaseVehicleListWindow::SetCargoFilterArray()
{
this->cargo_filter_criteria = CargoFilterCriteria::CF_ANY;
this->vehgroups.SetFilterFuncs(_filter_funcs);
this->vehgroups.SetFilterFuncs(_vehicle_group_filter_funcs);
this->vehgroups.SetFilterState(this->cargo_filter_criteria != CargoFilterCriteria::CF_ANY);
}
@@ -375,7 +447,7 @@ void BaseVehicleListWindow::FilterVehicleList()
if (this->vehicles.empty()) {
/* No vehicle passed through the filter, invalidate the previously selected vehicle */
this->vehicle_sel = INVALID_VEHICLE;
} else if (this->vehicle_sel != INVALID_VEHICLE && std::find(this->vehicles.begin(), this->vehicles.end(), Vehicle::Get(this->vehicle_sel)) == this->vehicles.end()) { // previously selected engine didn't pass the filter, remove selection
} else if (this->vehicle_sel != INVALID_VEHICLE && std::ranges::find(this->vehicles, Vehicle::Get(this->vehicle_sel)) == this->vehicles.end()) { // previously selected engine didn't pass the filter, remove selection
this->vehicle_sel = INVALID_VEHICLE;
}
}
@@ -431,17 +503,17 @@ DropDownList BaseVehicleListWindow::BuildCargoDropDownList(bool full) const
DropDownList list;
/* Add item for disabling filtering. */
list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY, false));
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY));
/* Add item for freight (i.e. vehicles with cargo capacity and with no passenger capacity). */
list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_FREIGHT), CargoFilterCriteria::CF_FREIGHT, false));
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_FREIGHT), CargoFilterCriteria::CF_FREIGHT));
/* Add item for vehicles not carrying anything, e.g. train engines. */
list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE, false));
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE));
/* Add cargos */
Dimension d = GetLargestCargoIconSize();
for (const CargoSpec *cs : _sorted_cargo_specs) {
if (!full && !HasBit(this->used_cargoes, cs->Index())) continue;
list.push_back(std::make_unique<DropDownListIconItem>(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false, !HasBit(this->used_cargoes, cs->Index())));
list.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false, !HasBit(this->used_cargoes, cs->Index())));
}
return list;
@@ -458,17 +530,26 @@ DropDownList BaseVehicleListWindow::BuildActionDropdownList(bool show_autoreplac
{
DropDownList list;
if (show_autoreplace) list.push_back(std::make_unique<DropDownListStringItem>(STR_VEHICLE_LIST_REPLACE_VEHICLES, ADI_REPLACE, false));
list.push_back(std::make_unique<DropDownListStringItem>(STR_VEHICLE_LIST_SEND_FOR_SERVICING, ADI_SERVICE, false));
list.push_back(std::make_unique<DropDownListStringItem>(this->vehicle_depot_name[this->vli.vtype], ADI_DEPOT, false));
if (show_group) {
list.push_back(std::make_unique<DropDownListStringItem>(STR_GROUP_ADD_SHARED_VEHICLE, ADI_ADD_SHARED, false));
list.push_back(std::make_unique<DropDownListStringItem>(STR_GROUP_REMOVE_ALL_VEHICLES, ADI_REMOVE_ALL, false));
} else if (show_create) {
list.push_back(std::make_unique<DropDownListStringItem>(STR_VEHICLE_LIST_CREATE_GROUP, ADI_CREATE_GROUP, false));
/* Autoreplace actions. */
if (show_autoreplace) {
list.push_back(MakeDropDownListStringItem(STR_VEHICLE_LIST_REPLACE_VEHICLES, ADI_REPLACE));
list.push_back(MakeDropDownListDividerItem());
}
/* Group actions. */
if (show_group) {
list.push_back(MakeDropDownListStringItem(STR_GROUP_ADD_SHARED_VEHICLE, ADI_ADD_SHARED));
list.push_back(MakeDropDownListStringItem(STR_GROUP_REMOVE_ALL_VEHICLES, ADI_REMOVE_ALL));
list.push_back(MakeDropDownListDividerItem());
} else if (show_create) {
list.push_back(MakeDropDownListStringItem(STR_VEHICLE_LIST_CREATE_GROUP, ADI_CREATE_GROUP));
list.push_back(MakeDropDownListDividerItem());
}
/* Depot actions. */
list.push_back(MakeDropDownListStringItem(STR_VEHICLE_LIST_SEND_FOR_SERVICING, ADI_SERVICE));
list.push_back(MakeDropDownListStringItem(this->vehicle_depot_name[this->vli.vtype], ADI_DEPOT));
return list;
}
@@ -519,7 +600,7 @@ static const uint MAX_REFIT_CYCLE = 256;
* @param dest_cargo_type Destination cargo type.
* @return the best sub type
*/
byte GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoID dest_cargo_type)
uint8_t GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoID dest_cargo_type)
{
v_from = v_from->GetFirstEnginePart();
v_for = v_for->GetFirstEnginePart();
@@ -533,7 +614,7 @@ byte GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoID dest_cargo_t
include(subtypes, GetCargoSubtypeText(v_from));
}
byte ret_refit_cyc = 0;
uint8_t ret_refit_cyc = 0;
bool success = false;
if (!subtypes.empty()) {
/* Check whether any articulated part is refittable to 'dest_cargo_type' with a subtype listed in 'subtypes' */
@@ -543,7 +624,7 @@ byte GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoID dest_cargo_t
if (!HasBit(e->info.refit_mask, dest_cargo_type) && v->cargo_type != dest_cargo_type) continue;
CargoID old_cargo_type = v->cargo_type;
byte old_cargo_subtype = v->cargo_subtype;
uint8_t old_cargo_subtype = v->cargo_subtype;
/* Set the 'destination' cargo */
v->cargo_type = dest_cargo_type;
@@ -559,7 +640,7 @@ byte GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoID dest_cargo_t
StringID subtype = GetCargoSubtypeText(v);
if (subtype == STR_EMPTY) break;
if (std::find(subtypes.begin(), subtypes.end(), subtype) == subtypes.end()) continue;
if (std::ranges::find(subtypes, subtype) == subtypes.end()) continue;
/* We found something matching. */
ret_refit_cyc = refit_cyc;
@@ -585,7 +666,7 @@ byte GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoID dest_cargo_t
/** Option to refit a vehicle chain */
struct RefitOption {
CargoID cargo; ///< Cargo to refit to
byte subtype; ///< Subcargo to use
uint8_t subtype; ///< Subcargo to use
StringID string; ///< GRF-local String to display for the cargo
/**
@@ -628,7 +709,7 @@ static void DrawVehicleRefitWindow(const RefitOptions &refits, const RefitOption
bool rtl = _current_text_dir == TD_RTL;
uint iconwidth = std::max(GetSpriteSize(SPR_CIRCLE_FOLDED).width, GetSpriteSize(SPR_CIRCLE_UNFOLDED).width);
uint iconheight = GetSpriteSize(SPR_CIRCLE_FOLDED).height;
int linecolour = _colour_gradient[COLOUR_ORANGE][4];
int linecolour = GetColourGradient(COLOUR_ORANGE, SHADE_NORMAL);
int iconleft = rtl ? ir.right - iconwidth : ir.left;
int iconcenter = rtl ? ir.right - iconwidth / 2 : ir.left + iconwidth / 2;
@@ -710,10 +791,10 @@ struct RefitWindow : public Window {
GetVehicleSet(vehicles_to_refit, Vehicle::Get(this->selected_vehicle), this->num_vehicles);
do {
if (v->type == VEH_TRAIN && std::find(vehicles_to_refit.begin(), vehicles_to_refit.end(), v->index) == vehicles_to_refit.end()) continue;
if (v->type == VEH_TRAIN && std::ranges::find(vehicles_to_refit, v->index) == vehicles_to_refit.end()) continue;
const Engine *e = v->GetEngine();
CargoTypes cmask = e->info.refit_mask;
byte callback_mask = e->info.callback_mask;
uint8_t callback_mask = e->info.callback_mask;
/* Skip this engine if it does not carry anything */
if (!e->CanCarryCargo()) continue;
@@ -741,7 +822,7 @@ struct RefitWindow : public Window {
/* Make a note of the original cargo type. It has to be
* changed to test the cargo & subtype... */
CargoID temp_cargo = v->cargo_type;
byte temp_subtype = v->cargo_subtype;
uint8_t temp_subtype = v->cargo_subtype;
v->cargo_type = cid;
@@ -861,7 +942,7 @@ struct RefitWindow : public Window {
this->selected_refit = nullptr;
}
RefitWindow(WindowDesc *desc, const Vehicle *v, VehicleOrderID order, bool auto_refit) : Window(desc)
RefitWindow(WindowDesc &desc, const Vehicle *v, VehicleOrderID order, bool auto_refit) : Window(desc)
{
this->auto_refit = auto_refit;
this->order = order;
@@ -910,20 +991,20 @@ struct RefitWindow : public Window {
this->DrawWidgets();
}
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
{
switch (widget) {
case WID_VR_MATRIX:
resize->height = GetCharacterHeight(FS_NORMAL) + padding.height;
size->height = resize->height * 8;
resize.height = GetCharacterHeight(FS_NORMAL) + padding.height;
size.height = resize.height * 8;
break;
case WID_VR_VEHICLE_PANEL_DISPLAY:
size->height = ScaleGUITrad(GetVehicleHeight(Vehicle::Get(this->window_number)->type));
size.height = ScaleGUITrad(GetVehicleHeight(Vehicle::Get(this->window_number)->type));
break;
case WID_VR_INFO:
size->width = this->information_width + padding.height;
size.width = this->information_width + padding.height;
break;
}
}
@@ -1004,7 +1085,7 @@ struct RefitWindow : public Window {
for (Train *u = Train::From(v); u != nullptr; u = u->Next()) {
/* Start checking. */
const bool contained = std::find(vehicles_to_refit.begin(), vehicles_to_refit.end(), u->index) != vehicles_to_refit.end();
const bool contained = std::ranges::find(vehicles_to_refit, u->index) != vehicles_to_refit.end();
if (contained && left == INT32_MIN) {
left = x - this->hscroll->GetPosition() + r.left + this->vehicle_margin;
width = 0;
@@ -1275,11 +1356,11 @@ static constexpr NWidgetPart _nested_vehicle_refit_widgets[] = {
EndContainer(),
};
static WindowDesc _vehicle_refit_desc(__FILE__, __LINE__,
static WindowDesc _vehicle_refit_desc(
WDP_AUTO, "view_vehicle_refit", 240, 174,
WC_VEHICLE_REFIT, WC_VEHICLE_VIEW,
WDF_CONSTRUCTION,
std::begin(_nested_vehicle_refit_widgets), std::end(_nested_vehicle_refit_widgets)
_nested_vehicle_refit_widgets
);
/**
@@ -1292,7 +1373,7 @@ static WindowDesc _vehicle_refit_desc(__FILE__, __LINE__,
void ShowVehicleRefitWindow(const Vehicle *v, VehicleOrderID order, Window *parent, bool auto_refit)
{
CloseWindowById(WC_VEHICLE_REFIT, v->index);
RefitWindow *w = new RefitWindow(&_vehicle_refit_desc, v, order, auto_refit);
RefitWindow *w = new RefitWindow(_vehicle_refit_desc, v, order, auto_refit);
w->parent = parent;
}
@@ -1553,19 +1634,19 @@ static constexpr NWidgetPart _nested_vehicle_list[] = {
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_VERTICAL),
NWidget(NWID_VERTICAL, NC_EQUALSIZE),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_VL_GROUP_ORDER), SetMinimalSize(0, 12), SetFill(1, 1), SetDataTip(STR_STATION_VIEW_GROUP, STR_TOOLTIP_GROUP_ORDER),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VL_SORT_ORDER), SetMinimalSize(0, 12), SetFill(1, 1), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
EndContainer(),
NWidget(NWID_VERTICAL),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_GROUP_BY_PULLDOWN), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(0x0, STR_TOOLTIP_GROUP_ORDER),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_SORT_BY_PULLDOWN), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA),
NWidget(NWID_VERTICAL, NC_EQUALSIZE),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_GROUP_BY_PULLDOWN), SetMinimalSize(0, 12), SetFill(1, 1), SetDataTip(0x0, STR_TOOLTIP_GROUP_ORDER),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_SORT_BY_PULLDOWN), SetMinimalSize(0, 12), SetFill(1, 1), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA),
EndContainer(),
NWidget(NWID_VERTICAL),
NWidget(NWID_VERTICAL, NC_EQUALSIZE),
NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 1), SetResize(1, 0), EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VL_FILTER_BY_CARGO_SEL),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_FILTER_BY_CARGO), SetMinimalSize(0, 12), SetFill(0, 0), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_FILTER_CRITERIA),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_FILTER_BY_CARGO), SetMinimalSize(0, 12), SetFill(0, 1), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_FILTER_CRITERIA),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 1), SetResize(1, 0), EndContainer(),
EndContainer(),
@@ -1585,9 +1666,9 @@ static constexpr NWidgetPart _nested_vehicle_list[] = {
NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetResize(1, 0), SetFill(1, 1), EndContainer(),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_MANAGE_VEHICLES_DROPDOWN), SetMinimalSize(118, 12), SetFill(0, 1),
SetDataTip(STR_VEHICLE_LIST_MANAGE_LIST, STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VL_STOP_ALL), SetMinimalSize(12, 12), SetFill(0, 1),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VL_STOP_ALL), SetAspect(WidgetDimensions::ASPECT_VEHICLE_FLAG), SetFill(0, 1),
SetDataTip(SPR_FLAG_VEH_STOPPED, STR_VEHICLE_LIST_MASS_STOP_LIST_TOOLTIP),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VL_START_ALL), SetMinimalSize(12, 12), SetFill(0, 1),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VL_START_ALL), SetAspect(WidgetDimensions::ASPECT_VEHICLE_FLAG), SetFill(0, 1),
SetDataTip(SPR_FLAG_VEH_RUNNING, STR_VEHICLE_LIST_MASS_START_LIST_TOOLTIP),
EndContainer(),
/* Widget to be shown for other companies hiding the previous 5 widgets. */
@@ -1719,10 +1800,9 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int
int vehicle_button_x = rtl ? ir.right - profit.width : ir.left;
uint max = static_cast<uint>(std::min<size_t>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehgroups.size()));
for (uint i = this->vscroll->GetPosition(); i < max; ++i) {
const GUIVehicleGroup &vehgroup = this->vehgroups[i];
auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->vehgroups);
for (auto it = first; it != last; ++it) {
const GUIVehicleGroup &vehgroup = *it;
SetDParam(0, vehgroup.GetDisplayProfitThisYear());
SetDParam(1, vehgroup.GetDisplayProfitLastYear());
@@ -1871,7 +1951,7 @@ private:
};
public:
VehicleListWindow(WindowDesc *desc, WindowNumber window_number) : BaseVehicleListWindow(desc, window_number)
VehicleListWindow(WindowDesc &desc, WindowNumber window_number) : BaseVehicleListWindow(desc, window_number)
{
this->CreateNestedTree();
@@ -1907,20 +1987,20 @@ public:
*this->sorting = this->vehgroups.GetListing();
}
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
{
switch (widget) {
case WID_VL_LIST:
resize->height = GetVehicleListHeight(this->vli.vtype, 1);
resize.height = GetVehicleListHeight(this->vli.vtype, 1);
switch (this->vli.vtype) {
case VEH_TRAIN:
case VEH_ROAD:
size->height = 6 * resize->height;
size.height = 6 * resize.height;
break;
case VEH_SHIP:
case VEH_AIRCRAFT:
size->height = 4 * resize->height;
size.height = 4 * resize.height;
break;
default: NOT_REACHED();
}
@@ -1930,31 +2010,31 @@ public:
Dimension d = GetStringBoundingBox(this->GetWidget<NWidgetCore>(widget)->widget_data);
d.width += padding.width + Window::SortButtonWidth() * 2; // Doubled since the string is centred and it also looks better.
d.height += padding.height;
*size = maxdim(*size, d);
size = maxdim(size, d);
break;
}
case WID_VL_GROUP_BY_PULLDOWN:
size->width = GetStringListWidth(this->vehicle_group_by_names) + padding.width;
size.width = GetStringListWidth(this->vehicle_group_by_names) + padding.width;
break;
case WID_VL_SORT_BY_PULLDOWN:
size->width = GetStringListWidth(this->vehicle_group_none_sorter_names_calendar);
size->width = std::max(size->width, GetStringListWidth(this->vehicle_group_none_sorter_names_wallclock));
size->width = std::max(size->width, GetStringListWidth(this->vehicle_group_shared_orders_sorter_names_calendar));
size->width = std::max(size->width, GetStringListWidth(this->vehicle_group_shared_orders_sorter_names_wallclock));
size->width += padding.width;
size.width = GetStringListWidth(this->vehicle_group_none_sorter_names_calendar);
size.width = std::max(size.width, GetStringListWidth(this->vehicle_group_none_sorter_names_wallclock));
size.width = std::max(size.width, GetStringListWidth(this->vehicle_group_shared_orders_sorter_names_calendar));
size.width = std::max(size.width, GetStringListWidth(this->vehicle_group_shared_orders_sorter_names_wallclock));
size.width += padding.width;
break;
case WID_VL_FILTER_BY_CARGO:
size->width = std::max(size->width, GetDropDownListDimension(this->BuildCargoDropDownList(true)).width + padding.width);
size.width = std::max(size.width, GetDropDownListDimension(this->BuildCargoDropDownList(true)).width + padding.width);
break;
case WID_VL_MANAGE_VEHICLES_DROPDOWN: {
Dimension d = this->GetActionDropdownSize(this->vli.type == VL_STANDARD, false, true);
d.height += padding.height;
d.width += padding.width;
*size = maxdim(*size, d);
size = maxdim(size, d);
break;
}
}
@@ -2043,7 +2123,7 @@ public:
}
/* Set text of group by dropdown widget. */
this->GetWidget<NWidgetCore>(WID_VL_GROUP_BY_PULLDOWN)->widget_data = this->vehicle_group_by_names[this->grouping];
this->GetWidget<NWidgetCore>(WID_VL_GROUP_BY_PULLDOWN)->widget_data = std::data(this->vehicle_group_by_names)[this->grouping];
/* Set text of sort by dropdown widget. */
this->GetWidget<NWidgetCore>(WID_VL_SORT_BY_PULLDOWN)->widget_data = this->GetVehicleSorterNames()[this->vehgroups.SortType()];
@@ -2053,6 +2133,15 @@ public:
this->DrawWidgets();
}
bool last_overlay_state;
void OnMouseLoop() override
{
if (last_overlay_state != ShowCargoIconOverlay()) {
last_overlay_state = ShowCargoIconOverlay();
this->SetDirty();
}
}
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
{
switch (widget) {
@@ -2216,18 +2305,18 @@ public:
}
};
static WindowDesc _vehicle_list_other_desc(__FILE__, __LINE__,
static WindowDesc _vehicle_list_other_desc(
WDP_AUTO, "list_vehicles", 260, 246,
WC_INVALID, WC_NONE,
0,
std::begin(_nested_vehicle_list), std::end(_nested_vehicle_list)
_nested_vehicle_list
);
static WindowDesc _vehicle_list_train_desc(__FILE__, __LINE__,
static WindowDesc _vehicle_list_train_desc(
WDP_AUTO, "list_vehicles_train", 325, 246,
WC_TRAINS_LIST, WC_NONE,
0,
std::begin(_nested_vehicle_list), std::end(_nested_vehicle_list)
_nested_vehicle_list
);
static void ShowVehicleListWindowLocal(CompanyID company, VehicleListType vlt, VehicleType vehicle_type, uint32_t unique_number)
@@ -2236,10 +2325,10 @@ static void ShowVehicleListWindowLocal(CompanyID company, VehicleListType vlt, V
WindowNumber num = VehicleListIdentifier(vlt, vehicle_type, company, unique_number).Pack();
if (vehicle_type == VEH_TRAIN) {
AllocateWindowDescFront<VehicleListWindow>(&_vehicle_list_train_desc, num);
AllocateWindowDescFront<VehicleListWindow>(_vehicle_list_train_desc, num);
} else {
_vehicle_list_other_desc.cls = GetWindowClassForVehicleType(vehicle_type);
AllocateWindowDescFront<VehicleListWindow>(&_vehicle_list_other_desc, num);
AllocateWindowDescFront<VehicleListWindow>(_vehicle_list_other_desc, num);
}
}
@@ -2357,14 +2446,12 @@ static StringID _service_interval_dropdown_calendar[] = {
STR_VEHICLE_DETAILS_DEFAULT,
STR_VEHICLE_DETAILS_DAYS,
STR_VEHICLE_DETAILS_PERCENT,
INVALID_STRING_ID,
};
static StringID _service_interval_dropdown_wallclock[] = {
STR_VEHICLE_DETAILS_DEFAULT,
STR_VEHICLE_DETAILS_MINUTES,
STR_VEHICLE_DETAILS_PERCENT,
INVALID_STRING_ID,
};
/** Class for managing the vehicle details window. */
@@ -2373,7 +2460,7 @@ struct VehicleDetailsWindow : Window {
Scrollbar *vscroll;
/** Initialize a newly created vehicle details window */
VehicleDetailsWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
VehicleDetailsWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc)
{
const Vehicle *v = Vehicle::Get(window_number);
@@ -2430,12 +2517,12 @@ struct VehicleDetailsWindow : Window {
return desired_height;
}
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
{
switch (widget) {
case WID_VD_TOP_DETAILS: {
Dimension dim = { 0, 0 };
size->height = 4 * GetCharacterHeight(FS_NORMAL) + padding.height;
size.height = 4 * GetCharacterHeight(FS_NORMAL) + padding.height;
for (uint i = 0; i < 4; i++) SetDParamMaxValue(i, INT16_MAX);
static const StringID info_strings[] = {
@@ -2446,12 +2533,12 @@ struct VehicleDetailsWindow : Window {
STR_VEHICLE_INFO_PROFIT_THIS_PERIOD_LAST_PERIOD_MIN_PERFORMANCE,
STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS
};
for (uint i = 0; i < lengthof(info_strings); i++) {
dim = maxdim(dim, GetStringBoundingBox(info_strings[i]));
for (const auto &info_string : info_strings) {
dim = maxdim(dim, GetStringBoundingBox(info_string));
}
SetDParam(0, STR_VEHICLE_INFO_AGE);
dim = maxdim(dim, GetStringBoundingBox(TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_INFO_AGE_RUNNING_COST_PERIOD : STR_VEHICLE_INFO_AGE_RUNNING_COST_YR));
size->width = dim.width + padding.width;
size.width = dim.width + padding.width;
break;
}
@@ -2459,15 +2546,15 @@ struct VehicleDetailsWindow : Window {
const Vehicle *v = Vehicle::Get(this->window_number);
switch (v->type) {
case VEH_ROAD:
size->height = this->GetRoadVehDetailsHeight(v) + padding.height;
size.height = this->GetRoadVehDetailsHeight(v) + padding.height;
break;
case VEH_SHIP:
size->height = 4 * GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal * 2 + padding.height;
size.height = 4 * GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal * 2 + padding.height;
break;
case VEH_AIRCRAFT:
size->height = 5 * GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal * 2 + padding.height;
size.height = 5 * GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal * 2 + padding.height;
break;
default:
@@ -2477,20 +2564,15 @@ struct VehicleDetailsWindow : Window {
}
case WID_VD_MATRIX:
resize->height = std::max<uint>(ScaleGUITrad(14), GetCharacterHeight(FS_NORMAL) + padding.height);
size->height = 4 * resize->height;
resize.height = std::max<uint>(ScaleGUITrad(14), GetCharacterHeight(FS_NORMAL) + padding.height);
size.height = 4 * resize.height;
break;
case WID_VD_SERVICE_INTERVAL_DROPDOWN: {
Dimension d{0, 0};
for (const StringID *strs : {_service_interval_dropdown_calendar, _service_interval_dropdown_wallclock}) {
while (*strs != INVALID_STRING_ID) {
d = maxdim(d, GetStringBoundingBox(*strs++));
}
}
Dimension d = maxdim(GetStringListBoundingBox(_service_interval_dropdown_calendar), GetStringListBoundingBox(_service_interval_dropdown_wallclock));
d.width += padding.width;
d.height += padding.height;
*size = maxdim(*size, d);
size = maxdim(size, d);
break;
}
@@ -2507,11 +2589,11 @@ struct VehicleDetailsWindow : Window {
/*/ Vehicle was last serviced at year 0, and we're at max year */
SetDParamMaxValue(2, TimerGameEconomy::DateAtStartOfYear(EconomyTime::MAX_YEAR));
}
size->width = std::max(
size.width = std::max(
GetStringBoundingBox(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT).width,
GetStringBoundingBox(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS).width
) + padding.width;
size->height = GetCharacterHeight(FS_NORMAL) + padding.height;
size.height = GetCharacterHeight(FS_NORMAL) + padding.height;
break;
}
}
@@ -2782,19 +2864,19 @@ struct VehicleDetailsWindow : Window {
};
/** Vehicle details window descriptor. */
static WindowDesc _train_vehicle_details_desc(__FILE__, __LINE__,
static WindowDesc _train_vehicle_details_desc(
WDP_AUTO, "view_vehicle_details_train", 405, 178,
WC_VEHICLE_DETAILS, WC_VEHICLE_VIEW,
0,
std::begin(_nested_train_vehicle_details_widgets), std::end(_nested_train_vehicle_details_widgets)
_nested_train_vehicle_details_widgets
);
/** Vehicle details window descriptor for other vehicles than a train. */
static WindowDesc _nontrain_vehicle_details_desc(__FILE__, __LINE__,
static WindowDesc _nontrain_vehicle_details_desc(
WDP_AUTO, "view_vehicle_details", 405, 113,
WC_VEHICLE_DETAILS, WC_VEHICLE_VIEW,
0,
std::begin(_nested_nontrain_vehicle_details_widgets), std::end(_nested_nontrain_vehicle_details_widgets)
_nested_nontrain_vehicle_details_widgets
);
/** Shows the vehicle details window of the given vehicle. */
@@ -2802,7 +2884,7 @@ static void ShowVehicleDetailsWindow(const Vehicle *v)
{
CloseWindowById(WC_VEHICLE_ORDERS, v->index, false);
CloseWindowById(WC_VEHICLE_TIMETABLE, v->index, false);
AllocateWindowDescFront<VehicleDetailsWindow>((v->type == VEH_TRAIN) ? &_train_vehicle_details_desc : &_nontrain_vehicle_details_desc, v->index);
AllocateWindowDescFront<VehicleDetailsWindow>((v->type == VEH_TRAIN) ? _train_vehicle_details_desc : _nontrain_vehicle_details_desc, v->index);
}
@@ -2812,9 +2894,9 @@ static void ShowVehicleDetailsWindow(const Vehicle *v)
static constexpr NWidgetPart _nested_vehicle_view_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_RENAME), SetMinimalSize(12, 14), SetDataTip(SPR_RENAME, STR_NULL /* filled in later */),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_RENAME), SetAspect(WidgetDimensions::ASPECT_RENAME), SetDataTip(SPR_RENAME, STR_NULL /* filled in later */),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_VV_CAPTION), SetDataTip(STR_VEHICLE_VIEW_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_LOCATION), SetMinimalSize(12, 14), SetDataTip(SPR_GOTO_LOCATION, STR_NULL /* filled in later */),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_LOCATION), SetAspect(WidgetDimensions::ASPECT_LOCATION), SetDataTip(SPR_GOTO_LOCATION, STR_NULL /* filled in later */),
NWidget(WWT_DEBUGBOX, COLOUR_GREY),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
@@ -2846,7 +2928,7 @@ static constexpr NWidgetPart _nested_vehicle_view_widgets[] = {
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_VV_START_STOP), SetResize(1, 0), SetFill(1, 0),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_ORDER_LOCATION), SetMinimalSize(12, 14), SetDataTip(SPR_GOTO_LOCATION, STR_VEHICLE_VIEW_ORDER_LOCATION_TOOLTIP),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_ORDER_LOCATION), SetAspect(WidgetDimensions::ASPECT_LOCATION), SetDataTip(SPR_GOTO_LOCATION, STR_VEHICLE_VIEW_ORDER_LOCATION_TOOLTIP),
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
EndContainer(),
};
@@ -2992,7 +3074,7 @@ private:
}
public:
VehicleViewWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
VehicleViewWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc)
{
this->flags |= WF_DISABLE_VP_SCROLL;
this->CreateNestedTree();
@@ -3056,24 +3138,24 @@ public:
this->Window::Close();
}
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
{
const Vehicle *v = Vehicle::Get(this->window_number);
switch (widget) {
case WID_VV_START_STOP:
size->height = std::max<uint>({size->height, (uint)GetCharacterHeight(FS_NORMAL), GetScaledSpriteSize(SPR_WARNING_SIGN).height, GetScaledSpriteSize(SPR_FLAG_VEH_STOPPED).height, GetScaledSpriteSize(SPR_FLAG_VEH_RUNNING).height}) + padding.height;
size.height = std::max<uint>({size.height, (uint)GetCharacterHeight(FS_NORMAL), GetScaledSpriteSize(SPR_WARNING_SIGN).height, GetScaledSpriteSize(SPR_FLAG_VEH_STOPPED).height, GetScaledSpriteSize(SPR_FLAG_VEH_RUNNING).height}) + padding.height;
break;
case WID_VV_FORCE_PROCEED:
if (v->type != VEH_TRAIN) {
size->height = 0;
size->width = 0;
size.height = 0;
size.width = 0;
}
break;
case WID_VV_VIEWPORT:
size->width = VV_INITIAL_VIEWPORT_WIDTH;
size->height = (v->type == VEH_TRAIN) ? VV_INITIAL_VIEWPORT_HEIGHT_TRAIN : VV_INITIAL_VIEWPORT_HEIGHT;
size.width = VV_INITIAL_VIEWPORT_WIDTH;
size.height = (v->type == VEH_TRAIN) ? VV_INITIAL_VIEWPORT_HEIGHT_TRAIN : VV_INITIAL_VIEWPORT_HEIGHT;
break;
}
}
@@ -3100,6 +3182,11 @@ public:
this->SetWidgetDisabledState(WID_VV_ORDER_LOCATION, v->current_order.GetLocation(v) == INVALID_TILE);
const Window *mainwindow = GetMainWindow();
if (mainwindow->viewport->follow_vehicle == v->index) {
this->LowerWidget(WID_VV_LOCATION);
}
this->DrawWidgets();
}
@@ -3186,7 +3273,7 @@ public:
break;
case OT_GOTO_WAYPOINT: {
assert(v->type == VEH_TRAIN || v->type == VEH_SHIP);
assert(v->type == VEH_TRAIN || v->type == VEH_ROAD || v->type == VEH_SHIP);
SetDParam(0, v->current_order.GetDestination());
str = HasBit(v->vehicle_flags, VF_PATHFINDER_LOST) ? STR_VEHICLE_STATUS_CANNOT_REACH_WAYPOINT_VEL : STR_VEHICLE_STATUS_HEADING_FOR_WAYPOINT_VEL;
SetDParam(1, PackVelocity(v->GetDisplaySpeed(), v->type));
@@ -3254,10 +3341,11 @@ public:
ShowExtraViewportWindow(TileVirtXY(v->x_pos, v->y_pos));
} else {
const Window *mainwindow = GetMainWindow();
if (click_count > 1 && mainwindow->viewport->zoom <= ZOOM_LVL_OUT_4X) {
if (click_count > 1) {
/* main window 'follows' vehicle */
mainwindow->viewport->follow_vehicle = v->index;
} else {
if (mainwindow->viewport->follow_vehicle == v->index) mainwindow->viewport->follow_vehicle = INVALID_VEHICLE;
ScrollMainWindowTo(v->x_pos, v->y_pos, v->z_pos);
}
}
@@ -3323,11 +3411,11 @@ public:
return Window::OnHotkey(hotkey);
}
void OnQueryTextFinished(char *str) override
void OnQueryTextFinished(std::optional<std::string> str) override
{
if (str == nullptr) return;
if (!str.has_value()) return;
Command<CMD_RENAME_VEHICLE>::Post(STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type, this->window_number, str);
Command<CMD_RENAME_VEHICLE>::Post(STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type, this->window_number, *str);
}
void OnMouseOver([[maybe_unused]] Point pt, WidgetID widget) override
@@ -3339,6 +3427,13 @@ public:
}
}
void OnMouseWheel(int wheel) override
{
if (_settings_client.gui.scrollwheel_scrolling != SWS_OFF) {
DoZoomInOutWindow(wheel < 0 ? ZOOM_IN : ZOOM_OUT, this);
}
}
void OnResize() override
{
if (this->viewport != nullptr) {
@@ -3408,11 +3503,11 @@ public:
};
/** Vehicle view window descriptor for all vehicles but trains. */
static WindowDesc _vehicle_view_desc(__FILE__, __LINE__,
static WindowDesc _vehicle_view_desc(
WDP_AUTO, "view_vehicle", 250, 116,
WC_VEHICLE_VIEW, WC_NONE,
0,
std::begin(_nested_vehicle_view_widgets), std::end(_nested_vehicle_view_widgets),
_nested_vehicle_view_widgets,
&VehicleViewWindow::hotkeys
);
@@ -3420,18 +3515,18 @@ static WindowDesc _vehicle_view_desc(__FILE__, __LINE__,
* Vehicle view window descriptor for trains. Only minimum_height and
* default_height are different for train view.
*/
static WindowDesc _train_view_desc(__FILE__, __LINE__,
static WindowDesc _train_view_desc(
WDP_AUTO, "view_vehicle_train", 250, 134,
WC_VEHICLE_VIEW, WC_NONE,
0,
std::begin(_nested_vehicle_view_widgets), std::end(_nested_vehicle_view_widgets),
_nested_vehicle_view_widgets,
&VehicleViewWindow::hotkeys
);
/** Shows the vehicle view window of the given vehicle. */
void ShowVehicleViewWindow(const Vehicle *v)
{
AllocateWindowDescFront<VehicleViewWindow>((v->type == VEH_TRAIN) ? &_train_view_desc : &_vehicle_view_desc, v->index);
AllocateWindowDescFront<VehicleViewWindow>((v->type == VEH_TRAIN) ? _train_view_desc : _vehicle_view_desc, v->index);
}
/**
@@ -3554,7 +3649,7 @@ void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type)
{
bool rtl = _current_text_dir == TD_RTL;
_cursor.sprite_count = 0;
_cursor.sprites.clear();
int total_width = 0;
int y_offset = 0;
bool rotor_seq = false; // Whether to draw the rotor of the vehicle in this step.
@@ -3574,18 +3669,12 @@ void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type)
v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq);
}
if (_cursor.sprite_count + seq.count > lengthof(_cursor.sprite_seq)) break;
int x_offs = 0;
if (v->type == VEH_TRAIN) x_offs = Train::From(v)->GetCursorImageOffset();
for (uint i = 0; i < seq.count; ++i) {
PaletteID pal2 = (v->vehstatus & VS_CRASHED) || !seq.seq[i].pal ? pal : seq.seq[i].pal;
_cursor.sprite_seq[_cursor.sprite_count].sprite = seq.seq[i].sprite;
_cursor.sprite_seq[_cursor.sprite_count].pal = pal2;
_cursor.sprite_pos[_cursor.sprite_count].x = rtl ? (-total_width + x_offs) : (total_width + x_offs);
_cursor.sprite_pos[_cursor.sprite_count].y = y_offset;
_cursor.sprite_count++;
_cursor.sprites.emplace_back(seq.seq[i].sprite, pal2, rtl ? (-total_width + x_offs) : (total_width + x_offs), y_offset);
}
if (v->type == VEH_AIRCRAFT && v->subtype == AIR_HELICOPTER && !rotor_seq) {
@@ -3601,8 +3690,8 @@ void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type)
/* Center trains and road vehicles on the front vehicle */
int offs = (ScaleSpriteTrad(VEHICLEINFO_FULL_VEHICLE_WIDTH) - total_width) / 2;
if (rtl) offs = -offs;
for (uint i = 0; i < _cursor.sprite_count; ++i) {
_cursor.sprite_pos[i].x += offs;
for (auto &cs : _cursor.sprites) {
cs.pos.x += offs;
}
}