OpenTTD Source: src/vehicle_gui.cpp Source File

OpenTTD Source 15.3

vehicle_gui.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#include "stdafx.h"
11#include "debug.h"
12#include "company_func.h"
13#include "gui.h"
14#include "textbuf_gui.h"
15#include "command_func.h"
16#include "vehicle_gui_base.h"
17#include "viewport_func.h"
18#include "newgrf_text.h"
19#include "newgrf_debug.h"
20#include "roadveh.h"
21#include "train.h"
22#include "aircraft.h"
23#include "depot_map.h"
24#include "group_gui.h"
25#include "strings_func.h"
26#include "vehicle_func.h"
27#include "autoreplace_gui.h"
28#include "string_func.h"
29#include "dropdown_type.h"
30#include "dropdown_func.h"
31#include "timetable.h"
32#include "articulated_vehicles.h"
33#include "core/geometry_func.hpp"
34#include "core/container_func.hpp"
35#include "company_base.h"
36#include "engine_func.h"
37#include "station_base.h"
38#include "tilehighlight_func.h"
39#include "zoom_func.h"
40#include "depot_cmd.h"
41#include "vehicle_cmd.h"
42#include "order_cmd.h"
43#include "roadveh_cmd.h"
44#include "train_cmd.h"
45#include "hotkeys.h"
46#include "group_cmd.h"
47
48#include "table/strings.h"
49
50#include "safeguards.h"
51
52
53static std::array<std::array<BaseVehicleListWindow::GroupBy, VEH_COMPANY_END>, VLT_END> _grouping{};
54static std::array<Sorting, BaseVehicleListWindow::GB_END> _sorting{};
55
56static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleNumberSorter;
57static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleNameSorter;
58static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleAgeSorter;
59static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleProfitThisYearSorter;
60static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleProfitLastYearSorter;
61static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleCargoSorter;
62static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleReliabilitySorter;
63static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleMaxSpeedSorter;
64static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleModelSorter;
65static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleValueSorter;
66static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleLengthSorter;
67static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleTimeToLiveSorter;
68static BaseVehicleListWindow::VehicleIndividualSortFunction VehicleTimetableDelaySorter;
69static BaseVehicleListWindow::VehicleGroupSortFunction VehicleGroupLengthSorter;
70static BaseVehicleListWindow::VehicleGroupSortFunction VehicleGroupTotalProfitThisYearSorter;
71static BaseVehicleListWindow::VehicleGroupSortFunction VehicleGroupTotalProfitLastYearSorter;
72static BaseVehicleListWindow::VehicleGroupSortFunction VehicleGroupAverageProfitThisYearSorter;
73static BaseVehicleListWindow::VehicleGroupSortFunction VehicleGroupAverageProfitLastYearSorter;
74
76template <BaseVehicleListWindow::VehicleIndividualSortFunction func>
77 static bool VehicleIndividualToGroupSorterWrapper(GUIVehicleGroup const &a, GUIVehicleGroup const &b)
78{
79 return func(*(a.vehicles_begin), *(b.vehicles_begin));
80}
81
82const std::initializer_list<BaseVehicleListWindow::VehicleGroupSortFunction * const> BaseVehicleListWindow::vehicle_group_none_sorter_funcs = {
83 &VehicleIndividualToGroupSorterWrapper<VehicleNumberSorter>,
84 &VehicleIndividualToGroupSorterWrapper<VehicleNameSorter>,
85 &VehicleIndividualToGroupSorterWrapper<VehicleAgeSorter>,
86 &VehicleIndividualToGroupSorterWrapper<VehicleProfitThisYearSorter>,
87 &VehicleIndividualToGroupSorterWrapper<VehicleProfitLastYearSorter>,
88 &VehicleIndividualToGroupSorterWrapper<VehicleCargoSorter>,
89 &VehicleIndividualToGroupSorterWrapper<VehicleReliabilitySorter>,
90 &VehicleIndividualToGroupSorterWrapper<VehicleMaxSpeedSorter>,
91 &VehicleIndividualToGroupSorterWrapper<VehicleModelSorter>,
92 &VehicleIndividualToGroupSorterWrapper<VehicleValueSorter>,
93 &VehicleIndividualToGroupSorterWrapper<VehicleLengthSorter>,
94 &VehicleIndividualToGroupSorterWrapper<VehicleTimeToLiveSorter>,
95 &VehicleIndividualToGroupSorterWrapper<VehicleTimetableDelaySorter>,
96};
97
98const std::initializer_list<const StringID> BaseVehicleListWindow::vehicle_group_none_sorter_names_calendar = {
99 STR_SORT_BY_NUMBER,
100 STR_SORT_BY_NAME,
101 STR_SORT_BY_AGE,
102 STR_SORT_BY_PROFIT_THIS_YEAR,
103 STR_SORT_BY_PROFIT_LAST_YEAR,
104 STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE,
105 STR_SORT_BY_RELIABILITY,
106 STR_SORT_BY_MAX_SPEED,
107 STR_SORT_BY_MODEL,
108 STR_SORT_BY_VALUE,
109 STR_SORT_BY_LENGTH,
110 STR_SORT_BY_LIFE_TIME,
111 STR_SORT_BY_TIMETABLE_DELAY,
112};
113
114const std::initializer_list<const StringID> BaseVehicleListWindow::vehicle_group_none_sorter_names_wallclock = {
115 STR_SORT_BY_NUMBER,
116 STR_SORT_BY_NAME,
117 STR_SORT_BY_AGE,
118 STR_SORT_BY_PROFIT_THIS_PERIOD,
119 STR_SORT_BY_PROFIT_LAST_PERIOD,
120 STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE,
121 STR_SORT_BY_RELIABILITY,
122 STR_SORT_BY_MAX_SPEED,
123 STR_SORT_BY_MODEL,
124 STR_SORT_BY_VALUE,
125 STR_SORT_BY_LENGTH,
126 STR_SORT_BY_LIFE_TIME,
127 STR_SORT_BY_TIMETABLE_DELAY,
128};
129
130const std::initializer_list<BaseVehicleListWindow::VehicleGroupSortFunction * const> BaseVehicleListWindow::vehicle_group_shared_orders_sorter_funcs = {
131 &VehicleGroupLengthSorter,
132 &VehicleGroupTotalProfitThisYearSorter,
133 &VehicleGroupTotalProfitLastYearSorter,
134 &VehicleGroupAverageProfitThisYearSorter,
135 &VehicleGroupAverageProfitLastYearSorter,
136};
137
138const std::initializer_list<const StringID> BaseVehicleListWindow::vehicle_group_shared_orders_sorter_names_calendar = {
139 STR_SORT_BY_NUM_VEHICLES,
140 STR_SORT_BY_TOTAL_PROFIT_THIS_YEAR,
141 STR_SORT_BY_TOTAL_PROFIT_LAST_YEAR,
142 STR_SORT_BY_AVERAGE_PROFIT_THIS_YEAR,
143 STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR,
144};
145
146const std::initializer_list<const StringID> BaseVehicleListWindow::vehicle_group_shared_orders_sorter_names_wallclock = {
147 STR_SORT_BY_NUM_VEHICLES,
148 STR_SORT_BY_TOTAL_PROFIT_THIS_PERIOD,
149 STR_SORT_BY_TOTAL_PROFIT_LAST_PERIOD,
150 STR_SORT_BY_AVERAGE_PROFIT_THIS_PERIOD,
151 STR_SORT_BY_AVERAGE_PROFIT_LAST_PERIOD,
152};
153
154const std::initializer_list<const StringID> BaseVehicleListWindow::vehicle_group_by_names = {
155 STR_GROUP_BY_NONE,
156 STR_GROUP_BY_SHARED_ORDERS,
157};
158
159const StringID BaseVehicleListWindow::vehicle_depot_name[] = {
160 STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT,
161 STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT,
162 STR_VEHICLE_LIST_SEND_SHIP_TO_DEPOT,
163 STR_VEHICLE_LIST_SEND_AIRCRAFT_TO_HANGAR
164};
165
166BaseVehicleListWindow::BaseVehicleListWindow(WindowDesc &desc, const VehicleListIdentifier &vli) : Window(desc), vli(vli)
167{
168 this->vehicle_sel = VehicleID::Invalid();
169 this->grouping = _grouping[vli.type][vli.vtype];
170 this->UpdateSortingFromGrouping();
171}
172
173std::span<const StringID> BaseVehicleListWindow::GetVehicleSorterNames() const
174{
175 switch (this->grouping) {
176 case GB_NONE:
177 return TimerGameEconomy::UsingWallclockUnits() ? vehicle_group_none_sorter_names_wallclock : vehicle_group_none_sorter_names_calendar;
178 case GB_SHARED_ORDERS:
179 return TimerGameEconomy::UsingWallclockUnits() ? vehicle_group_shared_orders_sorter_names_wallclock : vehicle_group_shared_orders_sorter_names_calendar;
180 default:
181 NOT_REACHED();
182 }
183}
184
190uint CountDigitsForAllocatingSpace(uint number)
191{
192 if (number >= 10000) return 5;
193 if (number >= 1000) return 4;
194 if (number >= 100) return 3;
195
196 /*
197 * When the smallest unit number is less than 10, it is
198 * quite likely that it will expand to become more than
199 * 10 quite soon.
200 */
201 return 2;
202}
203
209uint GetUnitNumberDigits(VehicleList &vehicles)
210{
211 uint unitnumber = 0;
212 for (const Vehicle *v : vehicles) {
213 unitnumber = std::max<uint>(unitnumber, v->unitnumber);
214 }
215
216 return CountDigitsForAllocatingSpace(unitnumber);
217}
218
219void BaseVehicleListWindow::BuildVehicleList()
220{
221 if (!this->vehgroups.NeedRebuild()) return;
222
223 Debug(misc, 3, "Building vehicle list type {} for company {} given index {}", this->vli.type, this->vli.company, this->vli.index);
224
225 this->vehgroups.clear();
226
227 GenerateVehicleSortList(&this->vehicles, this->vli);
228
229 CargoTypes used = 0;
230 for (const Vehicle *v : this->vehicles) {
231 for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
232 if (u->cargo_cap > 0) SetBit(used, u->cargo_type);
233 }
234 }
235 this->used_cargoes = used;
236
237 if (this->grouping == GB_NONE) {
238 uint max_unitnumber = 0;
239 for (auto it = this->vehicles.begin(); it != this->vehicles.end(); ++it) {
240 this->vehgroups.emplace_back(it, it + 1);
241
242 max_unitnumber = std::max<uint>(max_unitnumber, (*it)->unitnumber);
243 }
244 this->unitnumber_digits = CountDigitsForAllocatingSpace(max_unitnumber);
245 } else {
246 /* Sort by the primary vehicle; we just want all vehicles that share the same orders to form a contiguous range. */
247 std::stable_sort(this->vehicles.begin(), this->vehicles.end(), [](const Vehicle * const &u, const Vehicle * const &v) {
248 return u->FirstShared() < v->FirstShared();
249 });
250
251 uint max_num_vehicles = 0;
252
253 VehicleList::const_iterator begin = this->vehicles.begin();
254 while (begin != this->vehicles.end()) {
255 VehicleList::const_iterator end = std::find_if_not(begin, this->vehicles.cend(), [first_shared = (*begin)->FirstShared()](const Vehicle * const &v) {
256 return v->FirstShared() == first_shared;
257 });
258
259 this->vehgroups.emplace_back(begin, end);
260
261 max_num_vehicles = std::max<uint>(max_num_vehicles, static_cast<uint>(end - begin));
262
263 begin = end;
264 }
265
266 this->unitnumber_digits = CountDigitsForAllocatingSpace(max_num_vehicles);
267 }
268 this->FilterVehicleList();
269
270 this->vehgroups.RebuildDone();
271 this->vscroll->SetCount(this->vehgroups.size());
272}
273
281 static bool CargoFilterSingle(const Vehicle *v, const CargoType cargo_type)
282{
283 if (cargo_type == CargoFilterCriteria::CF_ANY) {
284 return true;
285 } else if (cargo_type == CargoFilterCriteria::CF_NONE) {
286 for (const Vehicle *w = v; w != nullptr; w = w->Next()) {
287 if (w->cargo_cap > 0) {
288 return false;
289 }
290 }
291 return true;
292 } else if (cargo_type == CargoFilterCriteria::CF_FREIGHT) {
293 bool have_capacity = false;
294 for (const Vehicle *w = v; w != nullptr; w = w->Next()) {
295 if (w->cargo_cap > 0) {
296 if (IsCargoInClass(w->cargo_type, CargoClass::Passengers)) {
297 return false;
298 } else {
299 have_capacity = true;
300 }
301 }
302 }
303 return have_capacity;
304 } else {
305 for (const Vehicle *w = v; w != nullptr; w = w->Next()) {
306 if (w->cargo_cap > 0 && w->cargo_type == cargo_type) {
307 return true;
308 }
309 }
310 return false;
311 }
312}
313
321 static bool CargoFilter(const GUIVehicleGroup *vehgroup, const CargoType cargo_type)
322{
323 auto it = vehgroup->vehicles_begin;
324
325 /* Check if any vehicle in the group matches; if so, the whole group does. */
326 for (; it != vehgroup->vehicles_end; it++) {
327 if (CargoFilterSingle(*it, cargo_type)) return true;
328 }
329
330 return false;
331}
332
337 bool ShowCargoIconOverlay()
338{
339 return _shift_pressed && _ctrl_pressed;
340}
341
349 void AddCargoIconOverlay(std::vector<CargoIconOverlay> &overlays, int x, int width, const Vehicle *v)
350{
351 bool rtl = _current_text_dir == TD_RTL;
352 if (!v->IsArticulatedPart() || v->cargo_type != v->Previous()->cargo_type) {
353 /* Add new overlay slot. */
354 overlays.emplace_back(rtl ? x - width : x, rtl ? x : x + width, v->cargo_type, v->cargo_cap);
355 } else {
356 /* This is an articulated part with the same cargo type, adjust left or right of last overlay slot. */
357 if (rtl) {
358 overlays.back().left -= width;
359 } else {
360 overlays.back().right += width;
361 }
362 overlays.back().cargo_cap += v->cargo_cap;
363 }
364}
365
372 void DrawCargoIconOverlay(int x, int y, CargoType cargo_type)
373{
374 if (!ShowCargoIconOverlay()) return;
375 if (!IsValidCargoType(cargo_type)) return;
376
377 const CargoSpec *cs = CargoSpec::Get(cargo_type);
378
379 SpriteID spr = cs->GetCargoIcon();
380 if (spr == 0) return;
381
382 Dimension d = GetSpriteSize(spr);
383 d.width /= 2;
384 d.height /= 2;
385 int one = ScaleGUITrad(1);
386
387 /* Draw the cargo icon in black shifted 4 times to create the outline. */
388 DrawSprite(spr, PALETTE_ALL_BLACK, x - d.width - one, y - d.height);
389 DrawSprite(spr, PALETTE_ALL_BLACK, x - d.width + one, y - d.height);
390 DrawSprite(spr, PALETTE_ALL_BLACK, x - d.width, y - d.height - one);
391 DrawSprite(spr, PALETTE_ALL_BLACK, x - d.width, y - d.height + one);
392 /* Draw the cargo icon normally. */
393 DrawSprite(spr, PAL_NONE, x - d.width, y - d.height);
394}
395
401 void DrawCargoIconOverlays(std::span<const CargoIconOverlay> overlays, int y)
402{
403 for (const auto &cio : overlays) {
404 if (cio.cargo_cap == 0) continue;
405 DrawCargoIconOverlay((cio.left + cio.right) / 2, y, cio.cargo_type);
406 }
407}
408
409static GUIVehicleGroupList::FilterFunction * const _vehicle_group_filter_funcs[] = {
410 &CargoFilter,
411};
412
417 void BaseVehicleListWindow::SetCargoFilter(CargoType cargo_type)
418{
419 if (this->cargo_filter_criteria != cargo_type) {
420 this->cargo_filter_criteria = cargo_type;
421 /* Deactivate filter if criteria is 'Show All', activate it otherwise. */
422 this->vehgroups.SetFilterState(this->cargo_filter_criteria != CargoFilterCriteria::CF_ANY);
423 this->vehgroups.SetFilterType(0);
424 this->vehgroups.ForceRebuild();
425 }
426}
427
431 void BaseVehicleListWindow::SetCargoFilterArray()
432{
433 this->cargo_filter_criteria = CargoFilterCriteria::CF_ANY;
434 this->vehgroups.SetFilterFuncs(_vehicle_group_filter_funcs);
435 this->vehgroups.SetFilterState(this->cargo_filter_criteria != CargoFilterCriteria::CF_ANY);
436}
437
441 void BaseVehicleListWindow::FilterVehicleList()
442{
443 this->vehgroups.Filter(this->cargo_filter_criteria);
444 if (this->vehicles.empty()) {
445 /* No vehicle passed through the filter, invalidate the previously selected vehicle */
446 this->vehicle_sel = VehicleID::Invalid();
447 } else if (this->vehicle_sel != VehicleID::Invalid() && std::ranges::find(this->vehicles, Vehicle::Get(this->vehicle_sel)) == this->vehicles.end()) { // previously selected engine didn't pass the filter, remove selection
448 this->vehicle_sel = VehicleID::Invalid();
449 }
450}
451
459 Dimension BaseVehicleListWindow::GetActionDropdownSize(bool show_autoreplace, bool show_group, bool show_create)
460{
461 Dimension d = {0, 0};
462
463 if (show_autoreplace) d = maxdim(d, GetStringBoundingBox(STR_VEHICLE_LIST_REPLACE_VEHICLES));
464 d = maxdim(d, GetStringBoundingBox(STR_VEHICLE_LIST_SEND_FOR_SERVICING));
465 d = maxdim(d, GetStringBoundingBox(this->vehicle_depot_name[this->vli.vtype]));
466
467 if (show_group) {
468 d = maxdim(d, GetStringBoundingBox(STR_GROUP_ADD_SHARED_VEHICLE));
469 d = maxdim(d, GetStringBoundingBox(STR_GROUP_REMOVE_ALL_VEHICLES));
470 } else if (show_create) {
471 d = maxdim(d, GetStringBoundingBox(STR_VEHICLE_LIST_CREATE_GROUP));
472 }
473
474 return d;
475}
476
477 void BaseVehicleListWindow::OnInit()
478{
479 this->order_arrow_width = std::max(GetStringBoundingBox(STR_JUST_LEFT_ARROW, FS_SMALL).width, GetStringBoundingBox(STR_JUST_RIGHT_ARROW, FS_SMALL).width);
480 this->SetCargoFilterArray();
481}
482
483 StringID BaseVehicleListWindow::GetCargoFilterLabel(CargoType cargo_type) const
484{
485 switch (cargo_type) {
486 case CargoFilterCriteria::CF_ANY: return STR_CARGO_TYPE_FILTER_ALL;
487 case CargoFilterCriteria::CF_FREIGHT: return STR_CARGO_TYPE_FILTER_FREIGHT;
488 case CargoFilterCriteria::CF_NONE: return STR_CARGO_TYPE_FILTER_NONE;
489 default: return CargoSpec::Get(cargo_type)->name;
490 }
491}
492
498 DropDownList BaseVehicleListWindow::BuildCargoDropDownList(bool full) const
499{
500 DropDownList list;
501
502 /* Add item for disabling filtering. */
503 list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY));
504 /* Add item for freight (i.e. vehicles with cargo capacity and with no passenger capacity). */
505 list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_FREIGHT), CargoFilterCriteria::CF_FREIGHT));
506 /* Add item for vehicles not carrying anything, e.g. train engines. */
507 list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE));
508
509 /* Add cargos */
510 Dimension d = GetLargestCargoIconSize();
511 for (const CargoSpec *cs : _sorted_cargo_specs) {
512 if (!full && !HasBit(this->used_cargoes, cs->Index())) continue;
513 list.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false, !HasBit(this->used_cargoes, cs->Index())));
514 }
515
516 return list;
517}
518
526 DropDownList BaseVehicleListWindow::BuildActionDropdownList(bool show_autoreplace, bool show_group, bool show_create)
527{
528 DropDownList list;
529
530 /* Autoreplace actions. */
531 if (show_autoreplace) {
532 list.push_back(MakeDropDownListStringItem(STR_VEHICLE_LIST_REPLACE_VEHICLES, ADI_REPLACE));
533 list.push_back(MakeDropDownListDividerItem());
534 }
535
536 /* Group actions. */
537 if (show_group) {
538 list.push_back(MakeDropDownListStringItem(STR_GROUP_ADD_SHARED_VEHICLE, ADI_ADD_SHARED));
539 list.push_back(MakeDropDownListStringItem(STR_GROUP_REMOVE_ALL_VEHICLES, ADI_REMOVE_ALL));
540 list.push_back(MakeDropDownListDividerItem());
541 } else if (show_create) {
542 list.push_back(MakeDropDownListStringItem(STR_VEHICLE_LIST_CREATE_GROUP, ADI_CREATE_GROUP));
543 list.push_back(MakeDropDownListDividerItem());
544 }
545
546 /* Depot actions. */
547 list.push_back(MakeDropDownListStringItem(STR_VEHICLE_LIST_SEND_FOR_SERVICING, ADI_SERVICE));
548 list.push_back(MakeDropDownListStringItem(this->vehicle_depot_name[this->vli.vtype], ADI_DEPOT));
549
550 return list;
551}
552
553/* cached values for VehicleNameSorter to spare many GetString() calls */
554static const Vehicle *_last_vehicle[2] = { nullptr, nullptr };
555
556void BaseVehicleListWindow::SortVehicleList()
557{
558 if (this->vehgroups.Sort()) return;
559
560 /* invalidate cached values for name sorter - vehicle names could change */
561 _last_vehicle[0] = _last_vehicle[1] = nullptr;
562}
563
564void DepotSortList(VehicleList *list)
565{
566 if (list->size() < 2) return;
567 std::sort(list->begin(), list->end(), &VehicleNumberSorter);
568}
569
571 static void DrawVehicleProfitButton(TimerGameEconomy::Date age, Money display_profit_last_year, uint num_vehicles, int x, int y)
572{
573 SpriteID spr;
574
575 /* draw profit-based coloured icons */
576 if (age <= VEHICLE_PROFIT_MIN_AGE) {
577 spr = SPR_PROFIT_NA;
578 } else if (display_profit_last_year < 0) {
579 spr = SPR_PROFIT_NEGATIVE;
580 } else if (display_profit_last_year < VEHICLE_PROFIT_THRESHOLD * num_vehicles) {
581 spr = SPR_PROFIT_SOME;
582 } else {
583 spr = SPR_PROFIT_LOT;
584 }
585 DrawSprite(spr, PAL_NONE, x, y);
586}
587
589 static const uint MAX_REFIT_CYCLE = 256;
590
600uint8_t GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoType dest_cargo_type)
601{
602 v_from = v_from->GetFirstEnginePart();
603 v_for = v_for->GetFirstEnginePart();
604
605 /* Create a list of subtypes used by the various parts of v_for */
606 static std::vector<StringID> subtypes;
607 subtypes.clear();
608 for (; v_from != nullptr; v_from = v_from->HasArticulatedPart() ? v_from->GetNextArticulatedPart() : nullptr) {
609 const Engine *e_from = v_from->GetEngine();
610 if (!e_from->CanCarryCargo() || !e_from->info.callback_mask.Test(VehicleCallbackMask::CargoSuffix)) continue;
611 include(subtypes, GetCargoSubtypeText(v_from));
612 }
613
614 uint8_t ret_refit_cyc = 0;
615 bool success = false;
616 if (!subtypes.empty()) {
617 /* Check whether any articulated part is refittable to 'dest_cargo_type' with a subtype listed in 'subtypes' */
618 for (Vehicle *v = v_for; v != nullptr; v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : nullptr) {
619 const Engine *e = v->GetEngine();
620 if (!e->CanCarryCargo() || !e->info.callback_mask.Test(VehicleCallbackMask::CargoSuffix)) continue;
621 if (!HasBit(e->info.refit_mask, dest_cargo_type) && v->cargo_type != dest_cargo_type) continue;
622
623 CargoType old_cargo_type = v->cargo_type;
624 uint8_t old_cargo_subtype = v->cargo_subtype;
625
626 /* Set the 'destination' cargo */
627 v->cargo_type = dest_cargo_type;
628
629 /* Cycle through the refits */
630 for (uint refit_cyc = 0; refit_cyc < MAX_REFIT_CYCLE; refit_cyc++) {
631 v->cargo_subtype = refit_cyc;
632
633 /* Make sure we don't pick up anything cached. */
634 v->First()->InvalidateNewGRFCache();
635 v->InvalidateNewGRFCache();
636
637 StringID subtype = GetCargoSubtypeText(v);
638 if (subtype == STR_EMPTY) break;
639
640 if (std::ranges::find(subtypes, subtype) == subtypes.end()) continue;
641
642 /* We found something matching. */
643 ret_refit_cyc = refit_cyc;
644 success = true;
645 break;
646 }
647
648 /* Reset the vehicle's cargo type */
649 v->cargo_type = old_cargo_type;
650 v->cargo_subtype = old_cargo_subtype;
651
652 /* Make sure we don't taint the vehicle. */
653 v->First()->InvalidateNewGRFCache();
654 v->InvalidateNewGRFCache();
655
656 if (success) break;
657 }
658 }
659
660 return ret_refit_cyc;
661}
662
664 struct RefitOption {
665 CargoType cargo;
666 uint8_t subtype;
667 StringID string;
668
674 inline bool operator == (const RefitOption &other) const
675 {
676 return other.cargo == this->cargo && other.string == this->string;
677 }
678};
679
680 using RefitOptions = std::map<CargoType, std::vector<RefitOption>, CargoTypeComparator>;
681
691 static void DrawVehicleRefitWindow(const RefitOptions &refits, const RefitOption *sel, uint pos, uint rows, uint delta, const Rect &r)
692{
693 Rect ir = r.Shrink(WidgetDimensions::scaled.matrix);
694 uint current = 0;
695
696 bool rtl = _current_text_dir == TD_RTL;
697 uint iconwidth = std::max(GetSpriteSize(SPR_CIRCLE_FOLDED).width, GetSpriteSize(SPR_CIRCLE_UNFOLDED).width);
698 uint iconheight = GetSpriteSize(SPR_CIRCLE_FOLDED).height;
699 PixelColour linecolour = GetColourGradient(COLOUR_ORANGE, SHADE_NORMAL);
700
701 int iconleft = rtl ? ir.right - iconwidth : ir.left;
702 int iconcenter = rtl ? ir.right - iconwidth / 2 : ir.left + iconwidth / 2;
703 int iconinner = rtl ? ir.right - iconwidth : ir.left + iconwidth;
704
705 Rect tr = ir.Indent(iconwidth + WidgetDimensions::scaled.hsep_wide, rtl);
706
707 /* Draw the list of subtypes for each cargo, and find the selected refit option (by its position). */
708 for (const auto &pair : refits) {
709 bool has_subtypes = pair.second.size() > 1;
710 for (const RefitOption &refit : pair.second) {
711 if (current >= pos + rows) break;
712
713 /* Hide subtypes if selected cargo type does not match */
714 if ((sel == nullptr || sel->cargo != refit.cargo) && refit.subtype != UINT8_MAX) continue;
715
716 /* Refit options with a position smaller than pos don't have to be drawn. */
717 if (current < pos) {
718 current++;
719 continue;
720 }
721
722 if (has_subtypes) {
723 if (refit.subtype != UINT8_MAX) {
724 /* Draw tree lines */
725 int ycenter = tr.top + GetCharacterHeight(FS_NORMAL) / 2;
726 GfxDrawLine(iconcenter, tr.top - WidgetDimensions::scaled.matrix.top, iconcenter, (&refit == &pair.second.back()) ? ycenter : tr.top - WidgetDimensions::scaled.matrix.top + delta - 1, linecolour);
727 GfxDrawLine(iconcenter, ycenter, iconinner, ycenter, linecolour);
728 } else {
729 /* Draw expand/collapse icon */
730 DrawSprite((sel != nullptr && sel->cargo == refit.cargo) ? SPR_CIRCLE_UNFOLDED : SPR_CIRCLE_FOLDED, PAL_NONE, iconleft, tr.top + (GetCharacterHeight(FS_NORMAL) - iconheight) / 2);
731 }
732 }
733
734 TextColour colour = (sel != nullptr && sel->cargo == refit.cargo && sel->subtype == refit.subtype) ? TC_WHITE : TC_BLACK;
735 /* Get the cargo name. */
736 DrawString(tr, GetString(STR_JUST_STRING_STRING, CargoSpec::Get(refit.cargo)->name, refit.string), colour);
737
738 tr.top += delta;
739 current++;
740 }
741 }
742}
743
745 struct RefitWindow : public Window {
746 const RefitOption *selected_refit = nullptr;
747 RefitOptions refit_list{};
748 VehicleOrderID order = INVALID_VEH_ORDER_ID;
749 uint information_width = 0;
750 Scrollbar *vscroll = nullptr;
751 Scrollbar *hscroll = nullptr;
752 int vehicle_width = 0;
753 int sprite_left = 0;
754 int sprite_right = 0;
755 uint vehicle_margin = 0;
756 int click_x = 0;
757 VehicleID selected_vehicle{};
758 uint8_t num_vehicles = 0;
759 bool auto_refit = false;
760
764 void BuildRefitList()
765 {
766 /* Store the currently selected RefitOption. */
767 std::optional<RefitOption> current_refit_option;
768 if (this->selected_refit != nullptr) current_refit_option = *(this->selected_refit);
769 this->selected_refit = nullptr;
770
771 this->refit_list.clear();
772 Vehicle *v = Vehicle::Get(this->window_number);
773
774 /* Check only the selected vehicles. */
775 VehicleSet vehicles_to_refit;
776 GetVehicleSet(vehicles_to_refit, Vehicle::Get(this->selected_vehicle), this->num_vehicles);
777
778 do {
779 if (v->type == VEH_TRAIN && std::ranges::find(vehicles_to_refit, v->index) == vehicles_to_refit.end()) continue;
780 const Engine *e = v->GetEngine();
781 CargoTypes cmask = e->info.refit_mask;
782 VehicleCallbackMasks callback_mask = e->info.callback_mask;
783
784 /* Skip this engine if it does not carry anything */
785 if (!e->CanCarryCargo()) continue;
786 /* Skip this engine if we build the list for auto-refitting and engine doesn't allow it. */
787 if (this->auto_refit && !e->info.misc_flags.Test(EngineMiscFlag::AutoRefit)) continue;
788
789 /* Loop through all cargoes in the refit mask */
790 for (const auto &cs : _sorted_cargo_specs) {
791 CargoType cargo_type = cs->Index();
792 /* Skip cargo type if it's not listed */
793 if (!HasBit(cmask, cargo_type)) continue;
794
795 auto &list = this->refit_list[cargo_type];
796 bool first_vehicle = list.empty();
797 if (first_vehicle) {
798 /* Keeping the current subtype is always an option. It also serves as the option in case of no subtypes */
799 list.emplace_back(cargo_type, UINT8_MAX, STR_EMPTY);
800 }
801
802 /* Check the vehicle's callback mask for cargo suffixes.
803 * This is not supported for ordered refits, since subtypes only have a meaning
804 * for a specific vehicle at a specific point in time, which conflicts with shared orders,
805 * autoreplace, autorenew, clone, order restoration, ... */
806 if (this->order == INVALID_VEH_ORDER_ID && callback_mask.Test(VehicleCallbackMask::CargoSuffix)) {
807 /* Make a note of the original cargo type. It has to be
808 * changed to test the cargo & subtype... */
809 CargoType temp_cargo = v->cargo_type;
810 uint8_t temp_subtype = v->cargo_subtype;
811
812 v->cargo_type = cargo_type;
813
814 for (uint refit_cyc = 0; refit_cyc < MAX_REFIT_CYCLE; refit_cyc++) {
815 v->cargo_subtype = refit_cyc;
816
817 /* Make sure we don't pick up anything cached. */
818 v->First()->InvalidateNewGRFCache();
819 v->InvalidateNewGRFCache();
820
821 StringID subtype = GetCargoSubtypeText(v);
822
823 if (first_vehicle) {
824 /* Append new subtype (don't add duplicates though) */
825 if (subtype == STR_EMPTY) break;
826
827 RefitOption option{cargo_type, static_cast<uint8_t>(refit_cyc), subtype};
828 include(list, option);
829 } else {
830 /* Intersect the subtypes of earlier vehicles with the subtypes of this vehicle */
831 if (subtype == STR_EMPTY) {
832 /* No more subtypes for this vehicle, delete all subtypes >= refit_cyc */
833 /* UINT8_MAX item is in front, other subtypes are sorted. So just truncate the list in the right spot */
834 for (uint i = 1; i < list.size(); i++) {
835 if (list[i].subtype >= refit_cyc) {
836 list.erase(list.begin() + i, list.end());
837 break;
838 }
839 }
840 break;
841 } else {
842 /* Check whether the subtype matches with the subtype of earlier vehicles. */
843 uint pos = 1;
844 while (pos < list.size() && list[pos].subtype != refit_cyc) pos++;
845 if (pos < list.size() && list[pos].string != subtype) {
846 /* String mismatch, remove item keeping the order */
847 list.erase(list.begin() + pos);
848 }
849 }
850 }
851 }
852
853 /* Reset the vehicle's cargo type */
854 v->cargo_type = temp_cargo;
855 v->cargo_subtype = temp_subtype;
856
857 /* And make sure we haven't tainted the cache */
858 v->First()->InvalidateNewGRFCache();
859 v->InvalidateNewGRFCache();
860 }
861 }
862 } while (v->IsGroundVehicle() && (v = v->Next()) != nullptr);
863
864 /* Restore the previously selected RefitOption. */
865 if (current_refit_option.has_value()) {
866 for (const auto &pair : this->refit_list) {
867 for (const auto &refit : pair.second) {
868 if (refit.cargo == current_refit_option->cargo && refit.subtype == current_refit_option->subtype) {
869 this->selected_refit = &refit;
870 break;
871 }
872 }
873 if (this->selected_refit != nullptr) break;
874 }
875 }
876
877 this->SetWidgetDisabledState(WID_VR_REFIT, this->selected_refit == nullptr);
878 }
879
883 void RefreshScrollbar()
884 {
885 size_t scroll_row = 0;
886 size_t rows = 0;
887 CargoType cargo = this->selected_refit == nullptr ? INVALID_CARGO : this->selected_refit->cargo;
888
889 for (const auto &pair : this->refit_list) {
890 if (pair.first == cargo) {
891 /* selected_refit points to an element in the vector so no need to search for it. */
892 scroll_row = rows + (this->selected_refit - pair.second.data());
893 rows += pair.second.size();
894 } else {
895 rows++; /* Unselected cargo type is collapsed into one row. */
896 }
897 }
898
899 this->vscroll->SetCount(rows);
900 this->vscroll->ScrollTowards(static_cast<int>(scroll_row));
901 }
902
907 void SetSelection(uint click_row)
908 {
909 uint row = 0;
910
911 for (const auto &pair : refit_list) {
912 for (const RefitOption &refit : pair.second) {
913 if (row == click_row) {
914 this->selected_refit = &refit;
915 return;
916 }
917 row++;
918 /* If this cargo type is not already selected then its subtypes are not visible, so skip the rest. */
919 if (this->selected_refit == nullptr || this->selected_refit->cargo != refit.cargo) break;
920 }
921 }
922
923 /* No selection made */
924 this->selected_refit = nullptr;
925 }
926
927 RefitWindow(WindowDesc &desc, const Vehicle *v, VehicleOrderID order, bool auto_refit) : Window(desc)
928 {
929 this->auto_refit = auto_refit;
930 this->order = order;
931 this->CreateNestedTree();
932
933 this->vscroll = this->GetScrollbar(WID_VR_SCROLLBAR);
934 this->hscroll = (v->IsGroundVehicle() ? this->GetScrollbar(WID_VR_HSCROLLBAR) : nullptr);
935 this->GetWidget<NWidgetCore>(WID_VR_SELECT_HEADER)->SetToolTip(STR_REFIT_TRAIN_LIST_TOOLTIP + v->type);
936 this->GetWidget<NWidgetCore>(WID_VR_MATRIX)->SetToolTip(STR_REFIT_TRAIN_LIST_TOOLTIP + v->type);
937 NWidgetCore *nwi = this->GetWidget<NWidgetCore>(WID_VR_REFIT);
938 nwi->SetStringTip(STR_REFIT_TRAIN_REFIT_BUTTON + v->type, STR_REFIT_TRAIN_REFIT_TOOLTIP + v->type);
939 this->GetWidget<NWidgetStacked>(WID_VR_SHOW_HSCROLLBAR)->SetDisplayedPlane(v->IsGroundVehicle() ? 0 : SZSP_HORIZONTAL);
940 this->GetWidget<NWidgetCore>(WID_VR_VEHICLE_PANEL_DISPLAY)->SetToolTip((v->type == VEH_TRAIN) ? STR_REFIT_SELECT_VEHICLES_TOOLTIP : STR_NULL);
941
942 this->FinishInitNested(v->index);
943 this->owner = v->owner;
944
945 this->SetWidgetDisabledState(WID_VR_REFIT, this->selected_refit == nullptr);
946 }
947
948 void OnInit() override
949 {
950 /* (Re)build the refit list */
951 this->OnInvalidateData(VIWD_CONSIST_CHANGED);
952 }
953
954 void OnPaint() override
955 {
956 /* Determine amount of items for scroller. */
957 if (this->hscroll != nullptr) this->hscroll->SetCount(this->vehicle_width);
958
959 /* Calculate sprite position. */
960 NWidgetCore *vehicle_panel_display = this->GetWidget<NWidgetCore>(WID_VR_VEHICLE_PANEL_DISPLAY);
961 int sprite_width = std::max(0, ((int)vehicle_panel_display->current_x - this->vehicle_width) / 2);
962 this->sprite_left = vehicle_panel_display->pos_x;
963 this->sprite_right = vehicle_panel_display->pos_x + vehicle_panel_display->current_x - 1;
964 if (_current_text_dir == TD_RTL) {
965 this->sprite_right -= sprite_width;
966 this->vehicle_margin = vehicle_panel_display->current_x - sprite_right;
967 } else {
968 this->sprite_left += sprite_width;
969 this->vehicle_margin = sprite_left;
970 }
971
972 this->DrawWidgets();
973 }
974
975 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
976 {
977 switch (widget) {
978 case WID_VR_MATRIX:
979 fill.height = resize.height = GetCharacterHeight(FS_NORMAL) + padding.height;
980 size.height = resize.height * 8;
981 break;
982
983 case WID_VR_VEHICLE_PANEL_DISPLAY:
984 size.height = ScaleGUITrad(GetVehicleHeight(Vehicle::Get(this->window_number)->type));
985 break;
986
987 case WID_VR_INFO:
988 size.width = this->information_width + padding.height;
989 break;
990 }
991 }
992
993 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
994 {
995 if (widget == WID_VR_CAPTION) return GetString(STR_REFIT_CAPTION, Vehicle::Get(this->window_number)->index);
996
997 return this->Window::GetWidgetString(widget, stringid);
998 }
999
1006 std::string GetCapacityString(const RefitOption &option) const
1007 {
1008 assert(_current_company == _local_company);
1009 auto [cost, refit_capacity, mail_capacity, cargo_capacities] = Command<CMD_REFIT_VEHICLE>::Do(DoCommandFlag::QueryCost, this->selected_vehicle, option.cargo, option.subtype, this->auto_refit, false, this->num_vehicles);
1010
1011 if (cost.Failed()) return {};
1012
1013 Money money = cost.GetCost();
1014 if (mail_capacity > 0) {
1015 if (this->order != INVALID_VEH_ORDER_ID) {
1016 /* No predictable cost */
1017 return GetString(STR_PURCHASE_INFO_AIRCRAFT_CAPACITY, option.cargo, refit_capacity, GetCargoTypeByLabel(CT_MAIL), mail_capacity);
1018 }
1019
1020 if (money <= 0) {
1021 return GetString(STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT, option.cargo, refit_capacity, GetCargoTypeByLabel(CT_MAIL), mail_capacity, -money);
1022 }
1023
1024 return GetString(STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT, option.cargo, refit_capacity, GetCargoTypeByLabel(CT_MAIL), mail_capacity, money);
1025 }
1026
1027 if (this->order != INVALID_VEH_ORDER_ID) {
1028 /* No predictable cost */
1029 return GetString(STR_PURCHASE_INFO_CAPACITY, option.cargo, refit_capacity, STR_EMPTY);
1030 }
1031
1032 if (money <= 0) {
1033 return GetString(STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT, option.cargo, refit_capacity, -money);
1034 }
1035
1036 return GetString(STR_REFIT_NEW_CAPACITY_COST_OF_REFIT, option.cargo, refit_capacity, money);
1037 }
1038
1039 void DrawWidget(const Rect &r, WidgetID widget) const override
1040 {
1041 switch (widget) {
1042 case WID_VR_VEHICLE_PANEL_DISPLAY: {
1043 Vehicle *v = Vehicle::Get(this->window_number);
1044 DrawVehicleImage(v, r.WithX(this->sprite_left, this->sprite_right),
1045 VehicleID::Invalid(), EIT_IN_DETAILS, this->hscroll != nullptr ? this->hscroll->GetPosition() : 0);
1046
1047 /* Highlight selected vehicles. */
1048 if (this->order != INVALID_VEH_ORDER_ID) break;
1049 int x = 0;
1050 switch (v->type) {
1051 case VEH_TRAIN: {
1052 VehicleSet vehicles_to_refit;
1053 GetVehicleSet(vehicles_to_refit, Vehicle::Get(this->selected_vehicle), this->num_vehicles);
1054
1055 int left = INT32_MIN;
1056 int width = 0;
1057
1058 /* Determine top & bottom position of the highlight.*/
1059 const int height = ScaleSpriteTrad(12);
1060 const int highlight_top = CentreBounds(r.top, r.bottom, height);
1061 const int highlight_bottom = highlight_top + height - 1;
1062
1063 for (Train *u = Train::From(v); u != nullptr; u = u->Next()) {
1064 /* Start checking. */
1065 const bool contained = std::ranges::find(vehicles_to_refit, u->index) != vehicles_to_refit.end();
1066 if (contained && left == INT32_MIN) {
1067 left = x - this->hscroll->GetPosition() + r.left + this->vehicle_margin;
1068 width = 0;
1069 }
1070
1071 /* Draw a selection. */
1072 if ((!contained || u->Next() == nullptr) && left != INT32_MIN) {
1073 if (u->Next() == nullptr && contained) {
1074 int current_width = u->GetDisplayImageWidth();
1075 width += current_width;
1076 x += current_width;
1077 }
1078
1079 int right = Clamp(left + width, 0, r.right);
1080 left = std::max(0, left);
1081
1082 if (_current_text_dir == TD_RTL) {
1083 right = r.Width() - left;
1084 left = right - width;
1085 }
1086
1087 if (left != right) {
1088 Rect hr = {left, highlight_top, right, highlight_bottom};
1089 DrawFrameRect(hr.Expand(WidgetDimensions::scaled.bevel), COLOUR_WHITE, FrameFlag::BorderOnly);
1090 }
1091
1092 left = INT32_MIN;
1093 }
1094
1095 int current_width = u->GetDisplayImageWidth();
1096 width += current_width;
1097 x += current_width;
1098 }
1099 break;
1100 }
1101
1102 default: break;
1103 }
1104 break;
1105 }
1106
1107 case WID_VR_MATRIX:
1108 DrawVehicleRefitWindow(this->refit_list, this->selected_refit, this->vscroll->GetPosition(), this->vscroll->GetCapacity(), this->resize.step_height, r);
1109 break;
1110
1111 case WID_VR_INFO:
1112 if (this->selected_refit != nullptr) {
1113 std::string string = this->GetCapacityString(*this->selected_refit);
1114 if (!string.empty()) {
1115 DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect), string);
1116 }
1117 }
1118 break;
1119 }
1120 }
1121
1127 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
1128 {
1129 switch (data) {
1130 case VIWD_AUTOREPLACE: // Autoreplace replaced the vehicle; selected_vehicle became invalid.
1131 case VIWD_CONSIST_CHANGED: { // The consist has changed; rebuild the entire list.
1132 /* Clear the selection. */
1133 Vehicle *v = Vehicle::Get(this->window_number);
1134 this->selected_vehicle = v->index;
1135 this->num_vehicles = UINT8_MAX;
1136 [[fallthrough]];
1137 }
1138
1139 case 2: { // The vehicle selection has changed; rebuild the entire list.
1140 if (!gui_scope) break;
1141 this->BuildRefitList();
1142
1143 /* The vehicle width has changed too. */
1144 this->vehicle_width = GetVehicleWidth(Vehicle::Get(this->window_number), EIT_IN_DETAILS);
1145 uint max_width = 0;
1146
1147 /* Check the width of all cargo information strings. */
1148 for (const auto &list : this->refit_list) {
1149 for (const RefitOption &refit : list.second) {
1150 std::string string = this->GetCapacityString(refit);
1151 if (!string.empty()) {
1152 Dimension dim = GetStringBoundingBox(string);
1153 max_width = std::max(dim.width, max_width);
1154 }
1155 }
1156 }
1157
1158 if (this->information_width < max_width) {
1159 this->information_width = max_width;
1160 this->ReInit();
1161 }
1162 [[fallthrough]];
1163 }
1164
1165 case 1: // A new cargo has been selected.
1166 if (!gui_scope) break;
1167 this->RefreshScrollbar();
1168 break;
1169 }
1170 }
1171
1172 int GetClickPosition(int click_x)
1173 {
1174 const NWidgetCore *matrix_widget = this->GetWidget<NWidgetCore>(WID_VR_VEHICLE_PANEL_DISPLAY);
1175 if (_current_text_dir == TD_RTL) click_x = matrix_widget->current_x - click_x;
1176 click_x -= this->vehicle_margin;
1177 if (this->hscroll != nullptr) click_x += this->hscroll->GetPosition();
1178
1179 return click_x;
1180 }
1181
1182 void SetSelectedVehicles(int drag_x)
1183 {
1184 drag_x = GetClickPosition(drag_x);
1185
1186 int left_x = std::min(this->click_x, drag_x);
1187 int right_x = std::max(this->click_x, drag_x);
1188 this->num_vehicles = 0;
1189
1190 Vehicle *v = Vehicle::Get(this->window_number);
1191 /* Find the vehicle part that was clicked. */
1192 switch (v->type) {
1193 case VEH_TRAIN: {
1194 /* Don't select anything if we are not clicking in the vehicle. */
1195 if (left_x >= 0) {
1196 const Train *u = Train::From(v);
1197 bool start_counting = false;
1198 for (; u != nullptr; u = u->Next()) {
1199 int current_width = u->GetDisplayImageWidth();
1200 left_x -= current_width;
1201 right_x -= current_width;
1202
1203 if (left_x < 0 && !start_counting) {
1204 this->selected_vehicle = u->index;
1205 start_counting = true;
1206
1207 /* Count the first vehicle, even if articulated part */
1208 this->num_vehicles++;
1209 } else if (start_counting && !u->IsArticulatedPart()) {
1210 /* Do not count articulated parts */
1211 this->num_vehicles++;
1212 }
1213
1214 if (right_x < 0) break;
1215 }
1216 }
1217
1218 /* If the selection is not correct, clear it. */
1219 if (this->num_vehicles != 0) {
1220 if (_ctrl_pressed) this->num_vehicles = UINT8_MAX;
1221 break;
1222 }
1223 [[fallthrough]];
1224 }
1225
1226 default:
1227 /* Clear the selection. */
1228 this->selected_vehicle = v->index;
1229 this->num_vehicles = UINT8_MAX;
1230 break;
1231 }
1232 }
1233
1234 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1235 {
1236 switch (widget) {
1237 case WID_VR_VEHICLE_PANEL_DISPLAY: { // Vehicle image.
1238 if (this->order != INVALID_VEH_ORDER_ID) break;
1239 NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_VR_VEHICLE_PANEL_DISPLAY);
1240 this->click_x = GetClickPosition(pt.x - nwi->pos_x);
1241 this->SetSelectedVehicles(pt.x - nwi->pos_x);
1242 this->SetWidgetDirty(WID_VR_VEHICLE_PANEL_DISPLAY);
1243 if (!_ctrl_pressed) {
1244 SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
1245 } else {
1246 /* The vehicle selection has changed. */
1247 this->InvalidateData(2);
1248 }
1249 break;
1250 }
1251
1252 case WID_VR_MATRIX: { // listbox
1253 this->SetSelection(this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_VR_MATRIX));
1254 this->SetWidgetDisabledState(WID_VR_REFIT, this->selected_refit == nullptr);
1255 this->InvalidateData(1);
1256
1257 if (click_count == 1) break;
1258 [[fallthrough]];
1259 }
1260
1261 case WID_VR_REFIT: // refit button
1262 if (this->selected_refit != nullptr) {
1263 const Vehicle *v = Vehicle::Get(this->window_number);
1264
1265 if (this->order == INVALID_VEH_ORDER_ID) {
1266 bool delete_window = this->selected_vehicle == v->index && this->num_vehicles == UINT8_MAX;
1267 if (Command<CMD_REFIT_VEHICLE>::Post(GetCmdRefitVehMsg(v), v->tile, this->selected_vehicle, this->selected_refit->cargo, this->selected_refit->subtype, false, false, this->num_vehicles) && delete_window) this->Close();
1268 } else {
1269 if (Command<CMD_ORDER_REFIT>::Post(v->tile, v->index, this->order, this->selected_refit->cargo)) this->Close();
1270 }
1271 }
1272 break;
1273 }
1274 }
1275
1276 void OnMouseDrag(Point pt, WidgetID widget) override
1277 {
1278 switch (widget) {
1279 case WID_VR_VEHICLE_PANEL_DISPLAY: { // Vehicle image.
1280 if (this->order != INVALID_VEH_ORDER_ID) break;
1281 NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_VR_VEHICLE_PANEL_DISPLAY);
1282 this->SetSelectedVehicles(pt.x - nwi->pos_x);
1283 this->SetWidgetDirty(WID_VR_VEHICLE_PANEL_DISPLAY);
1284 break;
1285 }
1286 }
1287 }
1288
1289 void OnDragDrop(Point pt, WidgetID widget) override
1290 {
1291 switch (widget) {
1292 case WID_VR_VEHICLE_PANEL_DISPLAY: { // Vehicle image.
1293 if (this->order != INVALID_VEH_ORDER_ID) break;
1294 NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_VR_VEHICLE_PANEL_DISPLAY);
1295 this->SetSelectedVehicles(pt.x - nwi->pos_x);
1296 this->InvalidateData(2);
1297 break;
1298 }
1299 }
1300 }
1301
1302 void OnResize() override
1303 {
1304 this->vehicle_width = GetVehicleWidth(Vehicle::Get(this->window_number), EIT_IN_DETAILS);
1305 this->vscroll->SetCapacityFromWidget(this, WID_VR_MATRIX);
1306 if (this->hscroll != nullptr) this->hscroll->SetCapacityFromWidget(this, WID_VR_VEHICLE_PANEL_DISPLAY);
1307 }
1308};
1309
1310static constexpr std::initializer_list<NWidgetPart> _nested_vehicle_refit_widgets = {
1311 NWidget(NWID_HORIZONTAL),
1312 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1313 NWidget(WWT_CAPTION, COLOUR_GREY, WID_VR_CAPTION),
1314 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
1315 EndContainer(),
1316 /* Vehicle display + scrollbar. */
1317 NWidget(NWID_VERTICAL),
1318 NWidget(WWT_PANEL, COLOUR_GREY, WID_VR_VEHICLE_PANEL_DISPLAY), SetMinimalSize(228, 14), SetResize(1, 0), SetScrollbar(WID_VR_HSCROLLBAR), EndContainer(),
1319 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VR_SHOW_HSCROLLBAR),
1320 NWidget(NWID_HSCROLLBAR, COLOUR_GREY, WID_VR_HSCROLLBAR),
1321 EndContainer(),
1322 EndContainer(),
1323 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_VR_SELECT_HEADER), SetStringTip(STR_REFIT_TITLE), SetResize(1, 0),
1324 /* Matrix + scrollbar. */
1325 NWidget(NWID_HORIZONTAL),
1326 NWidget(WWT_MATRIX, COLOUR_GREY, WID_VR_MATRIX), SetMinimalSize(228, 112), SetResize(1, 14), SetFill(1, 1), SetMatrixDataTip(1, 0), SetScrollbar(WID_VR_SCROLLBAR),
1327 NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_VR_SCROLLBAR),
1328 EndContainer(),
1329 NWidget(WWT_PANEL, COLOUR_GREY, WID_VR_INFO), SetMinimalTextLines(2, WidgetDimensions::unscaled.framerect.Vertical()), SetResize(1, 0), EndContainer(),
1330 NWidget(NWID_HORIZONTAL),
1331 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VR_REFIT), SetFill(1, 0), SetResize(1, 0),
1332 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
1333 EndContainer(),
1334};
1335
1336static WindowDesc _vehicle_refit_desc(
1337 WDP_AUTO, "view_vehicle_refit", 240, 174,
1338 WC_VEHICLE_REFIT, WC_VEHICLE_VIEW,
1339 WindowDefaultFlag::Construction,
1340 _nested_vehicle_refit_widgets
1341);
1342
1350 void ShowVehicleRefitWindow(const Vehicle *v, VehicleOrderID order, Window *parent, bool auto_refit)
1351{
1352 CloseWindowById(WC_VEHICLE_REFIT, v->index);
1353 RefitWindow *w = new RefitWindow(_vehicle_refit_desc, v, order, auto_refit);
1354 w->parent = parent;
1355}
1356
1358uint ShowRefitOptionsList(int left, int right, int y, EngineID engine)
1359{
1360 /* List of cargo types of this engine */
1361 CargoTypes cmask = GetUnionOfArticulatedRefitMasks(engine, false);
1362 /* List of cargo types available in this climate */
1363 CargoTypes lmask = _cargo_mask;
1364
1365 /* Draw nothing if the engine is not refittable */
1366 if (HasAtMostOneBit(cmask)) return y;
1367
1368 std::string str;
1369 if (cmask == lmask) {
1370 /* Engine can be refitted to all types in this climate */
1371 str = GetString(STR_PURCHASE_INFO_REFITTABLE_TO, STR_PURCHASE_INFO_ALL_TYPES, std::monostate{});
1372 } else {
1373 /* Check if we are able to refit to more cargo types and unable to. If
1374 * so, invert the cargo types to list those that we can't refit to. */
1375 if (CountBits(cmask ^ lmask) < CountBits(cmask) && CountBits(cmask ^ lmask) <= 7) {
1376 cmask ^= lmask;
1377 str = GetString(STR_PURCHASE_INFO_REFITTABLE_TO, STR_PURCHASE_INFO_ALL_BUT, cmask);
1378 } else {
1379 str = GetString(STR_PURCHASE_INFO_REFITTABLE_TO, STR_JUST_CARGO_LIST, cmask);
1380 }
1381 }
1382
1383 return DrawStringMultiLine(left, right, y, INT32_MAX, str);
1384}
1385
1387 StringID GetCargoSubtypeText(const Vehicle *v)
1388{
1389 if (!EngInfo(v->engine_type)->callback_mask.Test(VehicleCallbackMask::CargoSuffix)) return STR_EMPTY;
1390 std::array<int32_t, 1> regs100;
1391 uint16_t cb = GetVehicleCallback(CBID_VEHICLE_CARGO_SUFFIX, 0, 0, v->engine_type, v, regs100);
1392 if (v->GetGRF()->grf_version < 8 && cb == 0xFF) return STR_EMPTY;
1393 if (cb == CALLBACK_FAILED || cb == 0x400) return STR_EMPTY;
1394 if (cb == 0x40F) {
1395 return GetGRFStringID(v->GetGRFID(), static_cast<GRFStringID>(regs100[0]));
1396 }
1397 if (cb > 0x400) {
1398 ErrorUnknownCallbackResult(v->GetGRFID(), CBID_VEHICLE_CARGO_SUFFIX, cb);
1399 return STR_EMPTY;
1400 }
1401 return GetGRFStringID(v->GetGRFID(), GRFSTR_MISC_GRF_TEXT + cb);
1402}
1403
1405 static bool VehicleGroupLengthSorter(const GUIVehicleGroup &a, const GUIVehicleGroup &b)
1406{
1407 return a.NumVehicles() < b.NumVehicles();
1408}
1409
1411 static bool VehicleGroupTotalProfitThisYearSorter(const GUIVehicleGroup &a, const GUIVehicleGroup &b)
1412{
1413 return a.GetDisplayProfitThisYear() < b.GetDisplayProfitThisYear();
1414}
1415
1417 static bool VehicleGroupTotalProfitLastYearSorter(const GUIVehicleGroup &a, const GUIVehicleGroup &b)
1418{
1419 return a.GetDisplayProfitLastYear() < b.GetDisplayProfitLastYear();
1420}
1421
1423 static bool VehicleGroupAverageProfitThisYearSorter(const GUIVehicleGroup &a, const GUIVehicleGroup &b)
1424{
1425 return a.GetDisplayProfitThisYear() * static_cast<uint>(b.NumVehicles()) < b.GetDisplayProfitThisYear() * static_cast<uint>(a.NumVehicles());
1426}
1427
1429 static bool VehicleGroupAverageProfitLastYearSorter(const GUIVehicleGroup &a, const GUIVehicleGroup &b)
1430{
1431 return a.GetDisplayProfitLastYear() * static_cast<uint>(b.NumVehicles()) < b.GetDisplayProfitLastYear() * static_cast<uint>(a.NumVehicles());
1432}
1433
1435 static bool VehicleNumberSorter(const Vehicle * const &a, const Vehicle * const &b)
1436{
1437 return a->unitnumber < b->unitnumber;
1438}
1439
1441 static bool VehicleNameSorter(const Vehicle * const &a, const Vehicle * const &b)
1442{
1443 static std::string last_name[2] = { {}, {} };
1444
1445 if (a != _last_vehicle[0]) {
1446 _last_vehicle[0] = a;
1447 last_name[0] = GetString(STR_VEHICLE_NAME, a->index);
1448 }
1449
1450 if (b != _last_vehicle[1]) {
1451 _last_vehicle[1] = b;
1452 last_name[1] = GetString(STR_VEHICLE_NAME, b->index);
1453 }
1454
1455 int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting).
1456 return (r != 0) ? r < 0: VehicleNumberSorter(a, b);
1457}
1458
1460 static bool VehicleAgeSorter(const Vehicle * const &a, const Vehicle * const &b)
1461{
1462 auto r = a->age - b->age;
1463 return (r != 0) ? r < 0 : VehicleNumberSorter(a, b);
1464}
1465
1467 static bool VehicleProfitThisYearSorter(const Vehicle * const &a, const Vehicle * const &b)
1468{
1469 int r = ClampTo<int32_t>(a->GetDisplayProfitThisYear() - b->GetDisplayProfitThisYear());
1470 return (r != 0) ? r < 0 : VehicleNumberSorter(a, b);
1471}
1472
1474 static bool VehicleProfitLastYearSorter(const Vehicle * const &a, const Vehicle * const &b)
1475{
1476 int r = ClampTo<int32_t>(a->GetDisplayProfitLastYear() - b->GetDisplayProfitLastYear());
1477 return (r != 0) ? r < 0 : VehicleNumberSorter(a, b);
1478}
1479
1481 static bool VehicleCargoSorter(const Vehicle * const &a, const Vehicle * const &b)
1482{
1483 const Vehicle *v;
1484 CargoArray diff{};
1485
1486 /* Append the cargo of the connected waggons */
1487 for (v = a; v != nullptr; v = v->Next()) diff[v->cargo_type] += v->cargo_cap;
1488 for (v = b; v != nullptr; v = v->Next()) diff[v->cargo_type] -= v->cargo_cap;
1489
1490 int r = 0;
1491 for (uint d : diff) {
1492 r = d;
1493 if (r != 0) break;
1494 }
1495
1496 return (r != 0) ? r < 0 : VehicleNumberSorter(a, b);
1497}
1498
1500 static bool VehicleReliabilitySorter(const Vehicle * const &a, const Vehicle * const &b)
1501{
1502 int r = a->reliability - b->reliability;
1503 return (r != 0) ? r < 0 : VehicleNumberSorter(a, b);
1504}
1505
1507 static bool VehicleMaxSpeedSorter(const Vehicle * const &a, const Vehicle * const &b)
1508{
1509 int r = a->vcache.cached_max_speed - b->vcache.cached_max_speed;
1510 return (r != 0) ? r < 0 : VehicleNumberSorter(a, b);
1511}
1512
1514 static bool VehicleModelSorter(const Vehicle * const &a, const Vehicle * const &b)
1515{
1516 int r = a->engine_type.base() - b->engine_type.base();
1517 return (r != 0) ? r < 0 : VehicleNumberSorter(a, b);
1518}
1519
1521 static bool VehicleValueSorter(const Vehicle * const &a, const Vehicle * const &b)
1522{
1523 const Vehicle *u;
1524 Money diff = 0;
1525
1526 for (u = a; u != nullptr; u = u->Next()) diff += u->value;
1527 for (u = b; u != nullptr; u = u->Next()) diff -= u->value;
1528
1529 int r = ClampTo<int32_t>(diff);
1530 return (r != 0) ? r < 0 : VehicleNumberSorter(a, b);
1531}
1532
1534 static bool VehicleLengthSorter(const Vehicle * const &a, const Vehicle * const &b)
1535{
1536 int r = a->GetGroundVehicleCache()->cached_total_length - b->GetGroundVehicleCache()->cached_total_length;
1537 return (r != 0) ? r < 0 : VehicleNumberSorter(a, b);
1538}
1539
1541 static bool VehicleTimeToLiveSorter(const Vehicle * const &a, const Vehicle * const &b)
1542{
1543 int r = ClampTo<int32_t>((a->max_age - a->age) - (b->max_age - b->age));
1544 return (r != 0) ? r < 0 : VehicleNumberSorter(a, b);
1545}
1546
1548 static bool VehicleTimetableDelaySorter(const Vehicle * const &a, const Vehicle * const &b)
1549{
1550 int r = a->lateness_counter - b->lateness_counter;
1551 return (r != 0) ? r < 0 : VehicleNumberSorter(a, b);
1552}
1553
1554void InitializeGUI()
1555{
1556 _grouping = {};
1557 _sorting = {};
1558}
1559
1566 static inline void ChangeVehicleWindow(WindowClass window_class, VehicleID from_index, VehicleID to_index)
1567{
1568 Window *w = FindWindowById(window_class, from_index);
1569 if (w != nullptr) {
1570 /* Update window_number */
1571 w->window_number = to_index;
1572 if (w->viewport != nullptr) w->viewport->follow_vehicle = to_index;
1573
1574 /* Update vehicle drag data */
1575 if (_thd.window_class == window_class && _thd.window_number == from_index) {
1576 _thd.window_number = to_index;
1577 }
1578
1579 /* Notify the window. */
1580 w->InvalidateData(VIWD_AUTOREPLACE, false);
1581 }
1582}
1583
1589 void ChangeVehicleViewWindow(VehicleID from_index, VehicleID to_index)
1590{
1591 ChangeVehicleWindow(WC_VEHICLE_VIEW, from_index, to_index);
1592 ChangeVehicleWindow(WC_VEHICLE_ORDERS, from_index, to_index);
1593 ChangeVehicleWindow(WC_VEHICLE_REFIT, from_index, to_index);
1594 ChangeVehicleWindow(WC_VEHICLE_DETAILS, from_index, to_index);
1595 ChangeVehicleWindow(WC_VEHICLE_TIMETABLE, from_index, to_index);
1596}
1597
1598static constexpr std::initializer_list<NWidgetPart> _nested_vehicle_list = {
1599 NWidget(NWID_HORIZONTAL),
1600 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1601 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VL_CAPTION_SELECTION),
1602 NWidget(WWT_CAPTION, COLOUR_GREY, WID_VL_CAPTION),
1603 NWidget(NWID_HORIZONTAL),
1604 NWidget(WWT_CAPTION, COLOUR_GREY, WID_VL_CAPTION_SHARED_ORDERS),
1605 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VL_ORDER_VIEW), SetMinimalSize(61, 14), SetStringTip(STR_GOTO_ORDER_VIEW, STR_GOTO_ORDER_VIEW_TOOLTIP),
1606 EndContainer(),
1607 EndContainer(),
1608 NWidget(WWT_SHADEBOX, COLOUR_GREY),
1609 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
1610 NWidget(WWT_STICKYBOX, COLOUR_GREY),
1611 EndContainer(),
1612
1613 NWidget(NWID_HORIZONTAL),
1614 NWidget(NWID_VERTICAL, NWidContainerFlag::EqualSize),
1615 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_VL_GROUP_ORDER), SetMinimalSize(0, 12), SetFill(1, 1), SetStringTip(STR_STATION_VIEW_GROUP, STR_TOOLTIP_GROUP_ORDER),
1616 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VL_SORT_ORDER), SetMinimalSize(0, 12), SetFill(1, 1), SetStringTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
1617 EndContainer(),
1618 NWidget(NWID_VERTICAL, NWidContainerFlag::EqualSize),
1619 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_GROUP_BY_PULLDOWN), SetMinimalSize(0, 12), SetFill(1, 1), SetToolTip(STR_TOOLTIP_GROUP_ORDER),
1620 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_SORT_BY_PULLDOWN), SetMinimalSize(0, 12), SetFill(1, 1), SetToolTip(STR_TOOLTIP_SORT_CRITERIA),
1621 EndContainer(),
1622 NWidget(NWID_VERTICAL, NWidContainerFlag::EqualSize),
1623 NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 1), SetResize(1, 0), EndContainer(),
1624 NWidget(NWID_HORIZONTAL),
1625 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VL_FILTER_BY_CARGO_SEL),
1626 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_FILTER_BY_CARGO), SetMinimalSize(0, 12), SetFill(0, 1), SetToolTip(STR_TOOLTIP_FILTER_CRITERIA),
1627 EndContainer(),
1628 NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 1), SetResize(1, 0), EndContainer(),
1629 EndContainer(),
1630 EndContainer(),
1631 EndContainer(),
1632
1633 NWidget(NWID_HORIZONTAL),
1634 NWidget(WWT_MATRIX, COLOUR_GREY, WID_VL_LIST), SetMinimalSize(248, 0), SetFill(1, 0), SetResize(1, 1), SetMatrixDataTip(1, 0), SetScrollbar(WID_VL_SCROLLBAR),
1635 NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_VL_SCROLLBAR),
1636 EndContainer(),
1637
1638 NWidget(NWID_HORIZONTAL),
1639 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VL_HIDE_BUTTONS),
1640 NWidget(NWID_HORIZONTAL),
1641 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VL_AVAILABLE_VEHICLES), SetMinimalSize(106, 12), SetFill(0, 1),
1642 SetToolTip(STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP),
1643 NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetResize(1, 0), SetFill(1, 1), EndContainer(),
1644 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_MANAGE_VEHICLES_DROPDOWN), SetMinimalSize(118, 12), SetFill(0, 1),
1645 SetStringTip(STR_VEHICLE_LIST_MANAGE_LIST, STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP),
1646 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VL_STOP_ALL), SetAspect(WidgetDimensions::ASPECT_VEHICLE_FLAG), SetFill(0, 1),
1647 SetSpriteTip(SPR_FLAG_VEH_STOPPED, STR_VEHICLE_LIST_MASS_STOP_LIST_TOOLTIP),
1648 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VL_START_ALL), SetAspect(WidgetDimensions::ASPECT_VEHICLE_FLAG), SetFill(0, 1),
1649 SetSpriteTip(SPR_FLAG_VEH_RUNNING, STR_VEHICLE_LIST_MASS_START_LIST_TOOLTIP),
1650 EndContainer(),
1651 /* Widget to be shown for other companies hiding the previous 5 widgets. */
1652 NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 0), EndContainer(),
1653 EndContainer(),
1654 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
1655 EndContainer(),
1656};
1657
1658static void DrawSmallOrderList(const Vehicle *v, int left, int right, int y, uint order_arrow_width, VehicleOrderID start)
1659{
1660 auto orders = v->Orders();
1661 if (orders.empty()) return;
1662
1663 bool rtl = _current_text_dir == TD_RTL;
1664 int l_offset = rtl ? 0 : order_arrow_width;
1665 int r_offset = rtl ? order_arrow_width : 0;
1666 int i = 0;
1667 VehicleOrderID oid = start;
1668
1669 do {
1670 if (oid == v->cur_real_order_index) DrawString(left, right, y, rtl ? STR_JUST_LEFT_ARROW : STR_JUST_RIGHT_ARROW, TC_BLACK, SA_LEFT, false, FS_SMALL);
1671
1672 if (orders[oid].IsType(OT_GOTO_STATION)) {
1673 DrawString(left + l_offset, right - r_offset, y, GetString(STR_STATION_NAME, orders[oid].GetDestination()), TC_BLACK, SA_LEFT, false, FS_SMALL);
1674
1675 y += GetCharacterHeight(FS_SMALL);
1676 if (++i == 4) break;
1677 }
1678
1679 oid = v->orders->GetNext(oid);
1680 } while (oid != start);
1681}
1682
1684 static void DrawSmallOrderList(const OrderList *orderlist, int left, int right, int y, uint order_arrow_width)
1685{
1686 if (orderlist == nullptr) return;
1687
1688 bool rtl = _current_text_dir == TD_RTL;
1689 int l_offset = rtl ? 0 : order_arrow_width;
1690 int r_offset = rtl ? order_arrow_width : 0;
1691 int i = 0;
1692
1693 for (const Order &order : orderlist->GetOrders()) {
1694 if (order.IsType(OT_GOTO_STATION)) {
1695 DrawString(left + l_offset, right - r_offset, y, GetString(STR_STATION_NAME, order.GetDestination()), TC_BLACK, SA_LEFT, false, FS_SMALL);
1696
1697 y += GetCharacterHeight(FS_SMALL);
1698 if (++i == 4) break;
1699 }
1700 }
1701}
1702
1710 void DrawVehicleImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type, int skip)
1711{
1712 switch (v->type) {
1713 case VEH_TRAIN: DrawTrainImage(Train::From(v), r, selection, image_type, skip); break;
1714 case VEH_ROAD: DrawRoadVehImage(v, r, selection, image_type, skip); break;
1715 case VEH_SHIP: DrawShipImage(v, r, selection, image_type); break;
1716 case VEH_AIRCRAFT: DrawAircraftImage(v, r, selection, image_type); break;
1717 default: NOT_REACHED();
1718 }
1719}
1720
1727uint GetVehicleListHeight(VehicleType type, uint divisor)
1728{
1729 /* Name + vehicle + profit */
1730 uint base = ScaleGUITrad(GetVehicleHeight(type)) + 2 * GetCharacterHeight(FS_SMALL) + WidgetDimensions::scaled.matrix.Vertical();
1731 /* Drawing of the 4 small orders + profit*/
1732 if (type >= VEH_SHIP) base = std::max(base, 6U * GetCharacterHeight(FS_SMALL) + WidgetDimensions::scaled.matrix.Vertical());
1733
1734 if (divisor == 1) return base;
1735
1736 /* Make sure the height is dividable by divisor */
1737 uint rem = base % divisor;
1738 return base + (rem == 0 ? 0 : divisor - rem);
1739}
1740
1746 static int GetUnitNumberWidth(int digits)
1747{
1748 return GetStringBoundingBox(GetString(STR_JUST_COMMA, GetParamMaxDigits(digits))).width;
1749}
1750
1757 void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int line_height, const Rect &r) const
1758{
1759 Rect ir = r.WithHeight(line_height).Shrink(WidgetDimensions::scaled.matrix, RectPadding::zero);
1760 bool rtl = _current_text_dir == TD_RTL;
1761
1762 Dimension profit = GetSpriteSize(SPR_PROFIT_LOT);
1763 int text_offset = std::max<int>(profit.width, GetUnitNumberWidth(this->unitnumber_digits)) + WidgetDimensions::scaled.hsep_normal;
1764 Rect tr = ir.Indent(text_offset, rtl);
1765
1766 bool show_orderlist = this->vli.vtype >= VEH_SHIP;
1767 Rect olr = ir.Indent(std::max(ScaleGUITrad(100) + text_offset, ir.Width() / 2), rtl);
1768
1769 int image_left = (rtl && show_orderlist) ? olr.right : tr.left;
1770 int image_right = (!rtl && show_orderlist) ? olr.left : tr.right;
1771
1772 int vehicle_button_x = rtl ? ir.right - profit.width : ir.left;
1773
1774 auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->vehgroups);
1775 for (auto it = first; it != last; ++it) {
1776 const GUIVehicleGroup &vehgroup = *it;
1777
1778 DrawString(tr.left, tr.right, ir.bottom - GetCharacterHeight(FS_SMALL) - WidgetDimensions::scaled.framerect.bottom,
1779 GetString(TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_LIST_PROFIT_THIS_PERIOD_LAST_PERIOD : STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR,
1780 vehgroup.GetDisplayProfitThisYear(),
1781 vehgroup.GetDisplayProfitLastYear()));
1782
1783 DrawVehicleProfitButton(vehgroup.GetOldestVehicleAge(), vehgroup.GetDisplayProfitLastYear(), vehgroup.NumVehicles(), vehicle_button_x, ir.top + GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal);
1784
1785 switch (this->grouping) {
1786 case GB_NONE: {
1787 const Vehicle *v = vehgroup.GetSingleVehicle();
1788
1789 if (v->vehicle_flags.Test(VehicleFlag::PathfinderLost)) {
1790 DrawSprite(SPR_WARNING_SIGN, PAL_NONE, vehicle_button_x, ir.top + GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal + profit.height);
1791 }
1792
1793 DrawVehicleImage(v, ir.WithX(image_left, image_right), selected_vehicle, EIT_IN_LIST, 0);
1794
1795 if (_settings_client.gui.show_cargo_in_vehicle_lists) {
1796 /* Get the cargoes the vehicle can carry */
1797 CargoTypes vehicle_cargoes = 0;
1798
1799 for (auto u = v; u != nullptr; u = u->Next()) {
1800 if (u->cargo_cap == 0) continue;
1801
1802 SetBit(vehicle_cargoes, u->cargo_type);
1803 }
1804
1805 if (!v->name.empty()) {
1806 /* The vehicle got a name so we will print it and the cargoes */
1807 DrawString(tr.left, tr.right, ir.top,
1808 GetString(STR_VEHICLE_LIST_NAME_AND_CARGO, STR_VEHICLE_NAME, v->index, STR_VEHICLE_LIST_CARGO, vehicle_cargoes),
1809 TC_BLACK, SA_LEFT, false, FS_SMALL);
1810 } else if (v->group_id != DEFAULT_GROUP) {
1811 /* The vehicle has no name, but is member of a group, so print group name and the cargoes */
1812 DrawString(tr.left, tr.right, ir.top,
1813 GetString(STR_VEHICLE_LIST_NAME_AND_CARGO, STR_GROUP_NAME, v->group_id, STR_VEHICLE_LIST_CARGO, vehicle_cargoes),
1814 TC_BLACK, SA_LEFT, false, FS_SMALL);
1815 } else {
1816 /* The vehicle has no name, and is not a member of a group, so just print the cargoes */
1817 DrawString(tr.left, tr.right, ir.top, GetString(STR_VEHICLE_LIST_CARGO, vehicle_cargoes), TC_BLACK, SA_LEFT, false, FS_SMALL);
1818 }
1819 } else if (!v->name.empty()) {
1820 /* The vehicle got a name so we will print it */
1821 DrawString(tr.left, tr.right, ir.top, GetString(STR_VEHICLE_NAME, v->index), TC_BLACK, SA_LEFT, false, FS_SMALL);
1822 } else if (v->group_id != DEFAULT_GROUP) {
1823 /* The vehicle has no name, but is member of a group, so print group name */
1824 DrawString(tr.left, tr.right, ir.top, GetString(STR_GROUP_NAME, v->group_id), TC_BLACK, SA_LEFT, false, FS_SMALL);
1825 }
1826
1827 if (show_orderlist) DrawSmallOrderList(v, olr.left, olr.right, ir.top + GetCharacterHeight(FS_SMALL), this->order_arrow_width, v->cur_real_order_index);
1828
1829 TextColour tc;
1830 if (v->IsChainInDepot()) {
1831 tc = TC_BLUE;
1832 } else {
1833 tc = (v->age > v->max_age - CalendarTime::DAYS_IN_LEAP_YEAR) ? TC_RED : TC_BLACK;
1834 }
1835
1836 DrawString(ir.left, ir.right, ir.top + WidgetDimensions::scaled.framerect.top, GetString(STR_JUST_COMMA, v->unitnumber), tc);
1837 break;
1838 }
1839
1840 case GB_SHARED_ORDERS:
1841 assert(vehgroup.NumVehicles() > 0);
1842
1843 for (int i = 0; i < static_cast<int>(vehgroup.NumVehicles()); ++i) {
1844 if (image_left + WidgetDimensions::scaled.hsep_wide * i >= image_right) break; // Break if there is no more space to draw any more vehicles anyway.
1845 DrawVehicleImage(vehgroup.vehicles_begin[i], ir.WithX(image_left + WidgetDimensions::scaled.hsep_wide * i, image_right), selected_vehicle, EIT_IN_LIST, 0);
1846 }
1847
1848 if (show_orderlist) DrawSmallOrderList(vehgroup.vehicles_begin[0]->orders, olr.left, olr.right, ir.top + GetCharacterHeight(FS_SMALL), this->order_arrow_width);
1849
1850 DrawString(ir.left, ir.right, ir.top + WidgetDimensions::scaled.framerect.top, GetString(STR_JUST_COMMA, vehgroup.NumVehicles()), TC_BLACK);
1851 break;
1852
1853 default:
1854 NOT_REACHED();
1855 }
1856
1857 ir = ir.Translate(0, line_height);
1858 }
1859}
1860
1861void BaseVehicleListWindow::UpdateSortingFromGrouping()
1862{
1863 /* Set up sorting. Make the window-specific _sorting variable
1864 * point to the correct global _sorting struct so we are freed
1865 * from having conditionals during window operation */
1866 switch (this->vli.vtype) {
1867 case VEH_TRAIN: this->sorting = &_sorting[this->grouping].train; break;
1868 case VEH_ROAD: this->sorting = &_sorting[this->grouping].roadveh; break;
1869 case VEH_SHIP: this->sorting = &_sorting[this->grouping].ship; break;
1870 case VEH_AIRCRAFT: this->sorting = &_sorting[this->grouping].aircraft; break;
1871 default: NOT_REACHED();
1872 }
1873 this->vehgroups.SetSortFuncs(this->GetVehicleSorterFuncs());
1874 this->vehgroups.SetListing(*this->sorting);
1875 this->vehgroups.ForceRebuild();
1876 this->vehgroups.NeedResort();
1877}
1878
1879void BaseVehicleListWindow::UpdateVehicleGroupBy(GroupBy group_by)
1880{
1881 if (this->grouping != group_by) {
1882 /* Save the old sorting option, so that if we change the grouping option back later on,
1883 * UpdateSortingFromGrouping() will automatically restore the saved sorting option. */
1884 *this->sorting = this->vehgroups.GetListing();
1885
1886 this->grouping = group_by;
1887 _grouping[this->vli.type][this->vli.vtype] = group_by;
1888 this->UpdateSortingFromGrouping();
1889 }
1890}
1891
1896 struct VehicleListWindow : public BaseVehicleListWindow {
1897private:
1899 enum ButtonPlanes : uint8_t {
1900 BP_SHOW_BUTTONS,
1901 BP_HIDE_BUTTONS,
1902 };
1903
1905 enum CaptionPlanes : uint8_t {
1906 BP_NORMAL,
1907 BP_SHARED_ORDERS,
1908 };
1909
1910public:
1911 VehicleListWindow(WindowDesc &desc, WindowNumber window_number, const VehicleListIdentifier &vli) : BaseVehicleListWindow(desc, vli)
1912 {
1913 this->CreateNestedTree();
1914
1915 this->GetWidget<NWidgetStacked>(WID_VL_FILTER_BY_CARGO_SEL)->SetDisplayedPlane((this->vli.type == VL_SHARED_ORDERS) ? SZSP_NONE : 0);
1916
1917 this->vscroll = this->GetScrollbar(WID_VL_SCROLLBAR);
1918
1919 /* Set up the window widgets */
1920 this->GetWidget<NWidgetCore>(WID_VL_LIST)->SetToolTip(STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP + this->vli.vtype);
1921
1922 NWidgetStacked *nwi = this->GetWidget<NWidgetStacked>(WID_VL_CAPTION_SELECTION);
1923 if (this->vli.type == VL_SHARED_ORDERS) {
1924 this->GetWidget<NWidgetCore>(WID_VL_CAPTION_SHARED_ORDERS)->SetString(STR_VEHICLE_LIST_SHARED_ORDERS_LIST_CAPTION);
1925 /* If we are in the shared orders window, then disable the group-by dropdown menu.
1926 * Remove this when the group-by dropdown menu has another option apart from grouping by shared orders. */
1927 this->SetWidgetDisabledState(WID_VL_GROUP_ORDER, true);
1928 this->SetWidgetDisabledState(WID_VL_GROUP_BY_PULLDOWN, true);
1929 nwi->SetDisplayedPlane(BP_SHARED_ORDERS);
1930 } else {
1931 this->GetWidget<NWidgetCore>(WID_VL_CAPTION)->SetString(STR_VEHICLE_LIST_TRAIN_CAPTION + this->vli.vtype);
1932 nwi->SetDisplayedPlane(BP_NORMAL);
1933 }
1934
1935 this->FinishInitNested(window_number);
1936 if (this->vli.company != OWNER_NONE) this->owner = this->vli.company;
1937
1938 this->BuildVehicleList();
1939 this->SortVehicleList();
1940 }
1941
1942 ~VehicleListWindow()
1943 {
1944 *this->sorting = this->vehgroups.GetListing();
1945 }
1946
1947 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
1948 {
1949 switch (widget) {
1950 case WID_VL_LIST:
1951 fill.height = resize.height = GetVehicleListHeight(this->vli.vtype, 1);
1952
1953 switch (this->vli.vtype) {
1954 case VEH_TRAIN:
1955 case VEH_ROAD:
1956 size.height = 6 * resize.height;
1957 break;
1958 case VEH_SHIP:
1959 case VEH_AIRCRAFT:
1960 size.height = 4 * resize.height;
1961 break;
1962 default: NOT_REACHED();
1963 }
1964 break;
1965
1966 case WID_VL_SORT_ORDER: {
1967 Dimension d = GetStringBoundingBox(this->GetWidget<NWidgetCore>(widget)->GetString());
1968 d.width += padding.width + Window::SortButtonWidth() * 2; // Doubled since the string is centred and it also looks better.
1969 d.height += padding.height;
1970 size = maxdim(size, d);
1971 break;
1972 }
1973
1974 case WID_VL_GROUP_BY_PULLDOWN:
1975 size.width = GetStringListWidth(this->vehicle_group_by_names) + padding.width;
1976 break;
1977
1978 case WID_VL_SORT_BY_PULLDOWN:
1979 size.width = GetStringListWidth(this->vehicle_group_none_sorter_names_calendar);
1980 size.width = std::max(size.width, GetStringListWidth(this->vehicle_group_none_sorter_names_wallclock));
1981 size.width = std::max(size.width, GetStringListWidth(this->vehicle_group_shared_orders_sorter_names_calendar));
1982 size.width = std::max(size.width, GetStringListWidth(this->vehicle_group_shared_orders_sorter_names_wallclock));
1983 size.width += padding.width;
1984 break;
1985
1986 case WID_VL_FILTER_BY_CARGO:
1987 size.width = std::max(size.width, GetDropDownListDimension(this->BuildCargoDropDownList(true)).width + padding.width);
1988 break;
1989
1990 case WID_VL_MANAGE_VEHICLES_DROPDOWN: {
1991 Dimension d = this->GetActionDropdownSize(this->vli.type == VL_STANDARD, false, true);
1992 d.height += padding.height;
1993 d.width += padding.width;
1994 size = maxdim(size, d);
1995 break;
1996 }
1997 }
1998 }
1999
2000 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
2001 {
2002 switch (widget) {
2003 case WID_VL_AVAILABLE_VEHICLES:
2004 return GetString(STR_VEHICLE_LIST_AVAILABLE_TRAINS + this->vli.vtype);
2005
2006 case WID_VL_GROUP_BY_PULLDOWN:
2007 return GetString(std::data(this->vehicle_group_by_names)[this->grouping]);
2008
2009 case WID_VL_SORT_BY_PULLDOWN:
2010 return GetString(this->GetVehicleSorterNames()[this->vehgroups.SortType()]);
2011
2012 case WID_VL_FILTER_BY_CARGO:
2013 return GetString(this->GetCargoFilterLabel(this->cargo_filter_criteria));
2014
2015 case WID_VL_CAPTION:
2016 case WID_VL_CAPTION_SHARED_ORDERS: {
2017 switch (this->vli.type) {
2018 case VL_SHARED_ORDERS: // Shared Orders
2019 return GetString(stringid, this->vehicles.size());
2020
2021 case VL_STANDARD: // Company Name
2022 return GetString(stringid, STR_COMPANY_NAME, this->vli.ToCompanyID(), std::monostate{}, this->vehicles.size());
2023
2024 case VL_STATION_LIST: // Station/Waypoint Name
2025 return GetString(stringid, Station::IsExpected(BaseStation::Get(this->vli.ToStationID())) ? STR_STATION_NAME : STR_WAYPOINT_NAME, this->vli.ToStationID(), std::monostate{}, this->vehicles.size());
2026
2027 case VL_DEPOT_LIST:
2028 return GetString(stringid, STR_DEPOT_CAPTION, this->vli.vtype, this->vli.ToDestinationID(), this->vehicles.size());
2029
2030 default: NOT_REACHED();
2031 }
2032 }
2033
2034 default:
2035 return this->Window::GetWidgetString(widget, stringid);
2036 }
2037 }
2038
2039 void DrawWidget(const Rect &r, WidgetID widget) const override
2040 {
2041 switch (widget) {
2042 case WID_VL_SORT_ORDER:
2043 /* draw arrow pointing up/down for ascending/descending sorting */
2044 this->DrawSortButtonState(widget, this->vehgroups.IsDescSortOrder() ? SBS_DOWN : SBS_UP);
2045 break;
2046
2047 case WID_VL_LIST:
2048 this->DrawVehicleListItems(VehicleID::Invalid(), this->resize.step_height, r);
2049 break;
2050 }
2051 }
2052
2053 void OnPaint() override
2054 {
2055 this->BuildVehicleList();
2056 this->SortVehicleList();
2057
2058 if (this->vehicles.empty() && this->IsWidgetLowered(WID_VL_MANAGE_VEHICLES_DROPDOWN)) {
2059 this->CloseChildWindows(WC_DROPDOWN_MENU);
2060 }
2061
2062 /* Hide the widgets that we will not use in this window
2063 * Some windows contains actions only fit for the owner */
2064 int plane_to_show = (this->owner == _local_company) ? BP_SHOW_BUTTONS : BP_HIDE_BUTTONS;
2065 NWidgetStacked *nwi = this->GetWidget<NWidgetStacked>(WID_VL_HIDE_BUTTONS);
2066 if (plane_to_show != nwi->shown_plane) {
2067 nwi->SetDisplayedPlane(plane_to_show);
2068 nwi->SetDirty(this);
2069 }
2070 if (this->owner == _local_company) {
2071 this->SetWidgetDisabledState(WID_VL_AVAILABLE_VEHICLES, this->vli.type != VL_STANDARD);
2072 this->SetWidgetsDisabledState(this->vehicles.empty(),
2073 WID_VL_MANAGE_VEHICLES_DROPDOWN,
2074 WID_VL_STOP_ALL,
2075 WID_VL_START_ALL);
2076 }
2077
2078 this->DrawWidgets();
2079 }
2080
2081 bool last_overlay_state = false;
2082 void OnMouseLoop() override
2083 {
2084 if (last_overlay_state != ShowCargoIconOverlay()) {
2085 last_overlay_state = ShowCargoIconOverlay();
2086 this->SetDirty();
2087 }
2088 }
2089
2090 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
2091 {
2092 switch (widget) {
2093 case WID_VL_ORDER_VIEW: // Open the shared orders window
2094 assert(this->vli.type == VL_SHARED_ORDERS);
2095 assert(!this->vehicles.empty());
2096 ShowOrdersWindow(this->vehicles[0]);
2097 break;
2098
2099 case WID_VL_SORT_ORDER: // Flip sorting method ascending/descending
2100 this->vehgroups.ToggleSortOrder();
2101 this->SetDirty();
2102 break;
2103
2104 case WID_VL_GROUP_BY_PULLDOWN: // Select sorting criteria dropdown menu
2105 ShowDropDownMenu(this, this->vehicle_group_by_names, this->grouping, WID_VL_GROUP_BY_PULLDOWN, 0, 0);
2106 return;
2107
2108 case WID_VL_SORT_BY_PULLDOWN: // Select sorting criteria dropdown menu
2109 ShowDropDownMenu(this, this->GetVehicleSorterNames(), this->vehgroups.SortType(), WID_VL_SORT_BY_PULLDOWN, 0,
2110 (this->vli.vtype == VEH_TRAIN || this->vli.vtype == VEH_ROAD) ? 0 : (1 << 10));
2111 return;
2112
2113 case WID_VL_FILTER_BY_CARGO: // Cargo filter dropdown
2114 ShowDropDownList(this, this->BuildCargoDropDownList(false), this->cargo_filter_criteria, widget);
2115 break;
2116
2117 case WID_VL_LIST: { // Matrix to show vehicles
2118 auto it = this->vscroll->GetScrolledItemFromWidget(this->vehgroups, pt.y, this, WID_VL_LIST);
2119 if (it == this->vehgroups.end()) return; // click out of list bound
2120
2121 const GUIVehicleGroup &vehgroup = *it;
2122 switch (this->grouping) {
2123 case GB_NONE: {
2124 const Vehicle *v = vehgroup.GetSingleVehicle();
2125 if (!VehicleClicked(v)) {
2126 if (_ctrl_pressed) {
2127 ShowCompanyGroupForVehicle(v);
2128 } else {
2129 ShowVehicleViewWindow(v);
2130 }
2131 }
2132 break;
2133 }
2134
2135 case GB_SHARED_ORDERS: {
2136 assert(vehgroup.NumVehicles() > 0);
2137 if (!VehicleClicked(vehgroup)) {
2138 const Vehicle *v = vehgroup.vehicles_begin[0];
2139 if (_ctrl_pressed) {
2140 ShowOrdersWindow(v);
2141 } else {
2142 if (vehgroup.NumVehicles() == 1) {
2143 ShowVehicleViewWindow(v);
2144 } else {
2145 ShowVehicleListWindow(v);
2146 }
2147 }
2148 }
2149 break;
2150 }
2151
2152 default: NOT_REACHED();
2153 }
2154
2155 break;
2156 }
2157
2158 case WID_VL_AVAILABLE_VEHICLES:
2159 ShowBuildVehicleWindow(INVALID_TILE, this->vli.vtype);
2160 break;
2161
2162 case WID_VL_MANAGE_VEHICLES_DROPDOWN: {
2163 ShowDropDownList(this, this->BuildActionDropdownList(this->vli.type == VL_STANDARD, false, true), 0, WID_VL_MANAGE_VEHICLES_DROPDOWN);
2164 break;
2165 }
2166
2167 case WID_VL_STOP_ALL:
2168 case WID_VL_START_ALL:
2169 Command<CMD_MASS_START_STOP>::Post(TileIndex{}, widget == WID_VL_START_ALL, true, this->vli);
2170 break;
2171 }
2172 }
2173
2174 void OnDropdownSelect(WidgetID widget, int index, int) override
2175 {
2176 switch (widget) {
2177 case WID_VL_GROUP_BY_PULLDOWN:
2178 this->UpdateVehicleGroupBy(static_cast<GroupBy>(index));
2179 break;
2180
2181 case WID_VL_SORT_BY_PULLDOWN:
2182 this->vehgroups.SetSortType(index);
2183 break;
2184
2185 case WID_VL_FILTER_BY_CARGO:
2186 this->SetCargoFilter(index);
2187 break;
2188
2189 case WID_VL_MANAGE_VEHICLES_DROPDOWN:
2190 assert(!this->vehicles.empty());
2191
2192 switch (index) {
2193 case ADI_REPLACE: // Replace window
2194 ShowReplaceGroupVehicleWindow(ALL_GROUP, this->vli.vtype);
2195 break;
2196 case ADI_SERVICE: // Send for servicing
2197 case ADI_DEPOT: // Send to Depots
2198 Command<CMD_SEND_VEHICLE_TO_DEPOT>::Post(GetCmdSendToDepotMsg(this->vli.vtype), VehicleID::Invalid(), (index == ADI_SERVICE ? DepotCommandFlag::Service : DepotCommandFlags{}) | DepotCommandFlag::MassSend, this->vli);
2199 break;
2200
2201 case ADI_CREATE_GROUP: // Create group
2202 Command<CMD_ADD_VEHICLE_GROUP>::Post(CcAddVehicleNewGroup, NEW_GROUP, VehicleID::Invalid(), false, this->vli);
2203 break;
2204
2205 default: NOT_REACHED();
2206 }
2207 break;
2208
2209 default: NOT_REACHED();
2210 }
2211 this->SetDirty();
2212 }
2213
2214 void OnGameTick() override
2215 {
2216 if (this->vehgroups.NeedResort()) {
2217 StationID station = (this->vli.type == VL_STATION_LIST) ? this->vli.ToStationID() : StationID::Invalid();
2218
2219 Debug(misc, 3, "Periodic resort {} list company {} at station {}", this->vli.vtype, this->owner, station);
2220 this->SetDirty();
2221 }
2222 }
2223
2224 void OnResize() override
2225 {
2226 this->vscroll->SetCapacityFromWidget(this, WID_VL_LIST);
2227 }
2228
2234 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
2235 {
2236 if (!gui_scope && HasBit(data, 31) && this->vli.type == VL_SHARED_ORDERS) {
2237 /* Needs to be done in command-scope, so everything stays valid */
2238 this->vli.SetIndex(GB(data, 0, 20));
2239 this->window_number = this->vli.ToWindowNumber();
2240 this->vehgroups.ForceRebuild();
2241 return;
2242 }
2243
2244 if (data == 0) {
2245 /* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */
2246 this->vehgroups.ForceRebuild();
2247 } else {
2248 this->vehgroups.ForceResort();
2249 }
2250 }
2251};
2252
2253static WindowDesc _vehicle_list_desc[] = {
2254 {
2255 WDP_AUTO, "list_vehicles_train", 325, 246,
2256 WC_TRAINS_LIST, WC_NONE,
2257 {},
2258 _nested_vehicle_list
2259 },
2260 {
2261 WDP_AUTO, "list_vehicles_roadveh", 260, 246,
2262 WC_ROADVEH_LIST, WC_NONE,
2263 {},
2264 _nested_vehicle_list
2265 },
2266 {
2267 WDP_AUTO, "list_vehicles_ship", 260, 246,
2268 WC_SHIPS_LIST, WC_NONE,
2269 {},
2270 _nested_vehicle_list
2271 },
2272 {
2273 WDP_AUTO, "list_vehicles_aircraft", 260, 246,
2274 WC_AIRCRAFT_LIST, WC_NONE,
2275 {},
2276 _nested_vehicle_list
2277 }
2278};
2279
2280static void ShowVehicleListWindowLocal(CompanyID company, VehicleListType vlt, VehicleType vehicle_type, uint32_t unique_number)
2281{
2282 if (!Company::IsValidID(company) && company != OWNER_NONE) return;
2283
2284 assert(vehicle_type < std::size(_vehicle_list_desc));
2285 VehicleListIdentifier vli(vlt, vehicle_type, company, unique_number);
2286 AllocateWindowDescFront<VehicleListWindow>(_vehicle_list_desc[vehicle_type], vli.ToWindowNumber(), vli);
2287}
2288
2289void ShowVehicleListWindow(CompanyID company, VehicleType vehicle_type)
2290{
2291 /* If _settings_client.gui.advanced_vehicle_list > 1, display the Advanced list
2292 * if _settings_client.gui.advanced_vehicle_list == 1, display Advanced list only for local company
2293 * if _ctrl_pressed, do the opposite action (Advanced list x Normal list)
2294 */
2295
2296 if ((_settings_client.gui.advanced_vehicle_list > (uint)(company != _local_company)) != _ctrl_pressed) {
2297 ShowCompanyGroup(company, vehicle_type);
2298 } else {
2299 ShowVehicleListWindowLocal(company, VL_STANDARD, vehicle_type, company.base());
2300 }
2301}
2302
2303void ShowVehicleListWindow(const Vehicle *v)
2304{
2305 ShowVehicleListWindowLocal(v->owner, VL_SHARED_ORDERS, v->type, v->FirstShared()->index.base());
2306}
2307
2308void ShowVehicleListWindow(CompanyID company, VehicleType vehicle_type, StationID station)
2309{
2310 ShowVehicleListWindowLocal(company, VL_STATION_LIST, vehicle_type, station.base());
2311}
2312
2313void ShowVehicleListWindow(CompanyID company, VehicleType vehicle_type, TileIndex depot_tile)
2314{
2315 ShowVehicleListWindowLocal(company, VL_DEPOT_LIST, vehicle_type, GetDepotDestinationIndex(depot_tile).base());
2316}
2317
2318
2319/* Unified vehicle GUI - Vehicle Details Window */
2320
2321static_assert(WID_VD_DETAILS_CARGO_CARRIED == WID_VD_DETAILS_CARGO_CARRIED + TDW_TAB_CARGO );
2322static_assert(WID_VD_DETAILS_TRAIN_VEHICLES == WID_VD_DETAILS_CARGO_CARRIED + TDW_TAB_INFO );
2323static_assert(WID_VD_DETAILS_CAPACITY_OF_EACH == WID_VD_DETAILS_CARGO_CARRIED + TDW_TAB_CAPACITY);
2324static_assert(WID_VD_DETAILS_TOTAL_CARGO == WID_VD_DETAILS_CARGO_CARRIED + TDW_TAB_TOTALS );
2325
2327 static constexpr std::initializer_list<NWidgetPart> _nested_nontrain_vehicle_details_widgets = {
2328 NWidget(NWID_HORIZONTAL),
2329 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
2330 NWidget(WWT_CAPTION, COLOUR_GREY, WID_VD_CAPTION),
2331 NWidget(WWT_SHADEBOX, COLOUR_GREY),
2332 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
2333 NWidget(WWT_STICKYBOX, COLOUR_GREY),
2334 EndContainer(),
2335 NWidget(WWT_PANEL, COLOUR_GREY, WID_VD_TOP_DETAILS), SetMinimalSize(405, 42), SetResize(1, 0), EndContainer(),
2336 NWidget(WWT_PANEL, COLOUR_GREY, WID_VD_MIDDLE_DETAILS), SetMinimalSize(405, 45), SetResize(1, 0), EndContainer(),
2337 NWidget(NWID_HORIZONTAL),
2338 NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_VD_DECREASE_SERVICING_INTERVAL), SetFill(0, 1),
2339 SetArrowWidgetTypeTip(AWV_DECREASE),
2340 NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_VD_INCREASE_SERVICING_INTERVAL), SetFill(0, 1),
2341 SetArrowWidgetTypeTip(AWV_INCREASE),
2342 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VD_SERVICE_INTERVAL_DROPDOWN), SetFill(0, 1),
2343 SetStringTip(STR_EMPTY, STR_SERVICE_INTERVAL_DROPDOWN_TOOLTIP),
2344 NWidget(WWT_PANEL, COLOUR_GREY, WID_VD_SERVICING_INTERVAL), SetFill(1, 1), SetResize(1, 0), EndContainer(),
2345 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
2346 EndContainer(),
2347};
2348
2350 static constexpr std::initializer_list<NWidgetPart> _nested_train_vehicle_details_widgets = {
2351 NWidget(NWID_HORIZONTAL),
2352 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
2353 NWidget(WWT_CAPTION, COLOUR_GREY, WID_VD_CAPTION), SetStringTip(STR_VEHICLE_DETAILS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
2354 NWidget(WWT_SHADEBOX, COLOUR_GREY),
2355 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
2356 NWidget(WWT_STICKYBOX, COLOUR_GREY),
2357 EndContainer(),
2358 NWidget(WWT_PANEL, COLOUR_GREY, WID_VD_TOP_DETAILS), SetResize(1, 0), SetMinimalSize(405, 42), EndContainer(),
2359 NWidget(NWID_HORIZONTAL),
2360 NWidget(WWT_MATRIX, COLOUR_GREY, WID_VD_MATRIX), SetResize(1, 1), SetMinimalSize(393, 45), SetMatrixDataTip(1, 0), SetFill(1, 0), SetScrollbar(WID_VD_SCROLLBAR),
2361 NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_VD_SCROLLBAR),
2362 EndContainer(),
2363 NWidget(NWID_HORIZONTAL),
2364 NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_VD_DECREASE_SERVICING_INTERVAL), SetFill(0, 1),
2365 SetArrowWidgetTypeTip(AWV_DECREASE),
2366 NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_VD_INCREASE_SERVICING_INTERVAL), SetFill(0, 1),
2367 SetArrowWidgetTypeTip(AWV_INCREASE),
2368 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VD_SERVICE_INTERVAL_DROPDOWN), SetFill(0, 1),
2369 SetStringTip(STR_EMPTY, STR_SERVICE_INTERVAL_DROPDOWN_TOOLTIP),
2370 NWidget(WWT_PANEL, COLOUR_GREY, WID_VD_SERVICING_INTERVAL), SetFill(1, 1), SetResize(1, 0), EndContainer(),
2371 EndContainer(),
2372 NWidget(NWID_HORIZONTAL),
2373 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VD_DETAILS_CARGO_CARRIED), SetMinimalSize(96, 12),
2374 SetStringTip(STR_VEHICLE_DETAIL_TAB_CARGO, STR_VEHICLE_DETAILS_TRAIN_CARGO_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
2375 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VD_DETAILS_TRAIN_VEHICLES), SetMinimalSize(99, 12),
2376 SetStringTip(STR_VEHICLE_DETAIL_TAB_INFORMATION, STR_VEHICLE_DETAILS_TRAIN_INFORMATION_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
2377 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VD_DETAILS_CAPACITY_OF_EACH), SetMinimalSize(99, 12),
2378 SetStringTip(STR_VEHICLE_DETAIL_TAB_CAPACITIES, STR_VEHICLE_DETAILS_TRAIN_CAPACITIES_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
2379 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VD_DETAILS_TOTAL_CARGO), SetMinimalSize(99, 12),
2380 SetStringTip(STR_VEHICLE_DETAIL_TAB_TOTAL_CARGO, STR_VEHICLE_DETAILS_TRAIN_TOTAL_CARGO_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
2381 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
2382 EndContainer(),
2383};
2384
2385
2386extern int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab);
2387extern void DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16_t vscroll_cap, TrainDetailsWindowTabs det_tab);
2388extern void DrawRoadVehDetails(const Vehicle *v, const Rect &r);
2389extern void DrawShipDetails(const Vehicle *v, const Rect &r);
2390extern void DrawAircraftDetails(const Aircraft *v, const Rect &r);
2391
2392static const StringID _service_interval_dropdown_calendar[] = {
2393 STR_VEHICLE_DETAILS_DEFAULT,
2394 STR_VEHICLE_DETAILS_DAYS,
2395 STR_VEHICLE_DETAILS_PERCENT,
2396};
2397
2398static const StringID _service_interval_dropdown_wallclock[] = {
2399 STR_VEHICLE_DETAILS_DEFAULT,
2400 STR_VEHICLE_DETAILS_MINUTES,
2401 STR_VEHICLE_DETAILS_PERCENT,
2402};
2403
2405 struct VehicleDetailsWindow : Window {
2406 TrainDetailsWindowTabs tab = TDW_TAB_CARGO;
2407 Scrollbar *vscroll = nullptr;
2408
2410 VehicleDetailsWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc)
2411 {
2412 const Vehicle *v = Vehicle::Get(window_number);
2413
2414 this->CreateNestedTree();
2415 this->vscroll = (v->type == VEH_TRAIN ? this->GetScrollbar(WID_VD_SCROLLBAR) : nullptr);
2416 this->FinishInitNested(window_number);
2417
2418 this->owner = v->owner;
2419 }
2420
2426 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
2427 {
2428 if (data == VIWD_AUTOREPLACE) {
2429 /* Autoreplace replaced the vehicle.
2430 * Nothing to do for this window. */
2431 return;
2432 }
2433 if (!gui_scope) return;
2434 const Vehicle *v = Vehicle::Get(this->window_number);
2435 if (v->type == VEH_ROAD) {
2436 const NWidgetBase *nwid_info = this->GetWidget<NWidgetBase>(WID_VD_MIDDLE_DETAILS);
2437 uint aimed_height = this->GetRoadVehDetailsHeight(v);
2438 /* If the number of articulated parts changes, the size of the window must change too. */
2439 if (aimed_height != nwid_info->current_y) {
2440 this->ReInit();
2441 }
2442 }
2443 }
2444
2450 uint GetRoadVehDetailsHeight(const Vehicle *v)
2451 {
2452 uint desired_height;
2453 if (v->HasArticulatedPart()) {
2454 /* An articulated RV has its text drawn under the sprite instead of after it, hence 15 pixels extra. */
2455 desired_height = ScaleGUITrad(15) + 3 * GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal * 2;
2456 /* Add space for the cargo amount for each part. */
2457 for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
2458 if (u->cargo_cap != 0) desired_height += GetCharacterHeight(FS_NORMAL);
2459 }
2460 } else {
2461 desired_height = 4 * GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal * 2;
2462 }
2463 return desired_height;
2464 }
2465
2466 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
2467 {
2468 switch (widget) {
2469 case WID_VD_TOP_DETAILS: {
2470 Dimension dim = { 0, 0 };
2471 size.height = 4 * GetCharacterHeight(FS_NORMAL) + padding.height;
2472
2473 uint64_t max_value = GetParamMaxValue(INT16_MAX);
2474 dim = maxdim(dim, GetStringBoundingBox(GetString(STR_VEHICLE_INFO_MAX_SPEED, max_value)));
2475 dim = maxdim(dim, GetStringBoundingBox(GetString(STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED, max_value, max_value, max_value)));
2476 dim = maxdim(dim, GetStringBoundingBox(GetString(STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE, max_value, max_value, max_value, max_value)));
2477 dim = maxdim(dim, GetStringBoundingBox(GetString(STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE, max_value, max_value, max_value)));
2478 dim = maxdim(dim, GetStringBoundingBox(GetString(STR_VEHICLE_INFO_PROFIT_THIS_PERIOD_LAST_PERIOD_MIN_PERFORMANCE, max_value, max_value, max_value)));
2479 dim = maxdim(dim, GetStringBoundingBox(GetString(STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS, max_value, max_value)));
2480 dim = maxdim(dim, GetStringBoundingBox(GetString(TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_INFO_AGE_RUNNING_COST_PERIOD : STR_VEHICLE_INFO_AGE_RUNNING_COST_YR, STR_VEHICLE_INFO_AGE, max_value, max_value, max_value)));
2481 size.width = dim.width + padding.width;
2482 break;
2483 }
2484
2485 case WID_VD_MIDDLE_DETAILS: {
2486 const Vehicle *v = Vehicle::Get(this->window_number);
2487 switch (v->type) {
2488 case VEH_ROAD:
2489 size.height = this->GetRoadVehDetailsHeight(v) + padding.height;
2490 break;
2491
2492 case VEH_SHIP:
2493 size.height = 4 * GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal * 2 + padding.height;
2494 break;
2495
2496 case VEH_AIRCRAFT:
2497 size.height = 5 * GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal * 2 + padding.height;
2498 break;
2499
2500 default:
2501 NOT_REACHED(); // Train uses WID_VD_MATRIX instead.
2502 }
2503 break;
2504 }
2505
2506 case WID_VD_MATRIX:
2507 fill.height = resize.height = std::max<uint>(ScaleGUITrad(14), GetCharacterHeight(FS_NORMAL) + padding.height);
2508 size.height = 4 * resize.height;
2509 break;
2510
2511 case WID_VD_SERVICE_INTERVAL_DROPDOWN: {
2512 Dimension d = maxdim(GetStringListBoundingBox(_service_interval_dropdown_calendar), GetStringListBoundingBox(_service_interval_dropdown_wallclock));
2513 d.width += padding.width;
2514 d.height += padding.height;
2515 size = maxdim(size, d);
2516 break;
2517 }
2518
2519 case WID_VD_SERVICING_INTERVAL:
2520 /* Do we show the last serviced value as a date or minutes since service? */
2521 auto params = TimerGameEconomy::UsingWallclockUnits()
2522 ? MakeParameters(GetParamMaxValue(MAX_SERVINT_DAYS), STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO, EconomyTime::MAX_DATE)
2523 : MakeParameters(GetParamMaxValue(MAX_SERVINT_DAYS), STR_VEHICLE_DETAILS_LAST_SERVICE_DATE, TimerGameEconomy::DateAtStartOfYear(EconomyTime::MAX_YEAR));
2524
2525 size.width = std::max(size.width, GetStringBoundingBox(GetStringWithArgs(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT, params)).width);
2526 PrepareArgsForNextRun(params);
2527 size.width = std::max(size.width, GetStringBoundingBox(GetStringWithArgs(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS, params)).width);
2528
2529 size.width += padding.width;
2530 size.height = GetCharacterHeight(FS_NORMAL) + padding.height;
2531 break;
2532 }
2533 }
2534
2536 static bool IsVehicleServiceIntervalEnabled(const VehicleType vehicle_type, CompanyID company_id)
2537 {
2538 if (_local_company != company_id) return false;
2539
2540 const VehicleDefaultSettings *vds = &Company::Get(company_id)->settings.vehicle;
2541 switch (vehicle_type) {
2542 default: NOT_REACHED();
2543 case VEH_TRAIN: return vds->servint_trains != 0;
2544 case VEH_ROAD: return vds->servint_roadveh != 0;
2545 case VEH_SHIP: return vds->servint_ships != 0;
2546 case VEH_AIRCRAFT: return vds->servint_aircraft != 0;
2547 }
2548 }
2549
2559 static void DrawVehicleDetails(const Vehicle *v, const Rect &r, int vscroll_pos, uint vscroll_cap, TrainDetailsWindowTabs det_tab)
2560 {
2561 switch (v->type) {
2562 case VEH_TRAIN: DrawTrainDetails(Train::From(v), r, vscroll_pos, vscroll_cap, det_tab); break;
2563 case VEH_ROAD: DrawRoadVehDetails(v, r); break;
2564 case VEH_SHIP: DrawShipDetails(v, r); break;
2565 case VEH_AIRCRAFT: DrawAircraftDetails(Aircraft::From(v), r); break;
2566 default: NOT_REACHED();
2567 }
2568 }
2569
2570 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
2571 {
2572 if (widget == WID_VD_CAPTION) return GetString(STR_VEHICLE_DETAILS_CAPTION, Vehicle::Get(this->window_number)->index);
2573
2574 return this->Window::GetWidgetString(widget, stringid);
2575 }
2576
2577 void DrawWidget(const Rect &r, WidgetID widget) const override
2578 {
2579 const Vehicle *v = Vehicle::Get(this->window_number);
2580
2581 switch (widget) {
2582 case WID_VD_TOP_DETAILS: {
2583 Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
2584
2585 /* Draw running cost */
2586 DrawString(tr,
2587 GetString(TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_INFO_AGE_RUNNING_COST_PERIOD : STR_VEHICLE_INFO_AGE_RUNNING_COST_YR,
2588 (v->age + CalendarTime::DAYS_IN_YEAR < v->max_age) ? STR_VEHICLE_INFO_AGE : STR_VEHICLE_INFO_AGE_RED,
2589 TimerGameCalendar::DateToYear(v->age),
2590 TimerGameCalendar::DateToYear(v->max_age),
2591 v->GetDisplayRunningCost()));
2592 tr.top += GetCharacterHeight(FS_NORMAL);
2593
2594 /* Draw max speed */
2595 uint64_t max_speed = PackVelocity(v->GetDisplayMaxSpeed(), v->type);
2596 if (v->type == VEH_TRAIN ||
2597 (v->type == VEH_ROAD && _settings_game.vehicle.roadveh_acceleration_model != AM_ORIGINAL)) {
2598 const GroundVehicleCache *gcache = v->GetGroundVehicleCache();
2599 if (v->type == VEH_TRAIN && (_settings_game.vehicle.train_acceleration_model == AM_ORIGINAL ||
2600 Train::From(v)->GetAccelerationType() == VehicleAccelerationModel::Maglev)) {
2601 DrawString(tr, GetString(STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED, gcache->cached_weight, gcache->cached_power, max_speed));
2602 } else {
2603 DrawString(tr, GetString(STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE, gcache->cached_weight, gcache->cached_power, max_speed, gcache->cached_max_te));
2604 }
2605 } else if (v->type == VEH_AIRCRAFT) {
2606 StringID type = v->GetEngine()->GetAircraftTypeText();
2607 if (Aircraft::From(v)->GetRange() > 0) {
2608 DrawString(tr, GetString(STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE, max_speed, type, Aircraft::From(v)->GetRange()));
2609 } else {
2610 DrawString(tr, GetString(STR_VEHICLE_INFO_MAX_SPEED_TYPE, max_speed, type));
2611 }
2612 } else {
2613 DrawString(tr, GetString(STR_VEHICLE_INFO_MAX_SPEED, max_speed));
2614 }
2615 tr.top += GetCharacterHeight(FS_NORMAL);
2616
2617 /* Draw profit */
2618 if (v->IsGroundVehicle()) {
2619 DrawString(tr,
2620 GetString(TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_INFO_PROFIT_THIS_PERIOD_LAST_PERIOD_MIN_PERFORMANCE : STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE,
2621 v->GetDisplayProfitThisYear(),
2622 v->GetDisplayProfitLastYear(),
2623 v->GetDisplayMinPowerToWeight()));
2624 } else {
2625 DrawString(tr,
2626 GetString(TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_INFO_PROFIT_THIS_PERIOD_LAST_PERIOD : STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR,
2627 v->GetDisplayProfitThisYear(),
2628 v->GetDisplayProfitLastYear()));
2629 }
2630 tr.top += GetCharacterHeight(FS_NORMAL);
2631
2632 /* Draw breakdown & reliability */
2633 DrawString(tr, GetString(STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS, ToPercent16(v->reliability), v->breakdowns_since_last_service));
2634 break;
2635 }
2636
2637 case WID_VD_MATRIX: {
2638 /* For trains only. */
2639 DrawVehicleDetails(v, r.Shrink(WidgetDimensions::scaled.matrix, RectPadding::zero).WithHeight(this->resize.step_height), this->vscroll->GetPosition(), this->vscroll->GetCapacity(), this->tab);
2640 break;
2641 }
2642
2643 case WID_VD_MIDDLE_DETAILS: {
2644 /* For other vehicles, at the place of the matrix. */
2645 bool rtl = _current_text_dir == TD_RTL;
2646 uint sprite_width = GetSingleVehicleWidth(v, EIT_IN_DETAILS) + WidgetDimensions::scaled.framerect.Horizontal();
2647 Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
2648
2649 /* Articulated road vehicles use a complete line. */
2650 if (v->type == VEH_ROAD && v->HasArticulatedPart()) {
2651 DrawVehicleImage(v, tr.WithHeight(ScaleGUITrad(GetVehicleHeight(v->type)), false), VehicleID::Invalid(), EIT_IN_DETAILS, 0);
2652 } else {
2653 Rect sr = tr.WithWidth(sprite_width, rtl);
2654 DrawVehicleImage(v, sr.WithHeight(ScaleGUITrad(GetVehicleHeight(v->type)), false), VehicleID::Invalid(), EIT_IN_DETAILS, 0);
2655 }
2656
2657 DrawVehicleDetails(v, tr.Indent(sprite_width, rtl), 0, 0, this->tab);
2658 break;
2659 }
2660
2661 case WID_VD_SERVICING_INTERVAL: {
2662 /* Draw service interval text */
2663 Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
2664
2665 /* We're using wallclock units. Show minutes since last serviced. */
2666 if (TimerGameEconomy::UsingWallclockUnits()) {
2667 int minutes_since_serviced = (TimerGameEconomy::date - v->date_of_last_service).base() / EconomyTime::DAYS_IN_ECONOMY_MONTH;
2668 DrawString(tr.left, tr.right, CentreBounds(r.top, r.bottom, GetCharacterHeight(FS_NORMAL)),
2669 GetString(v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT : STR_VEHICLE_DETAILS_SERVICING_INTERVAL_MINUTES,
2670 v->GetServiceInterval(), STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO, minutes_since_serviced));
2671 break;
2672 }
2673
2674 /* We're using calendar dates. Show the date of last service. */
2675 DrawString(tr.left, tr.right, CentreBounds(r.top, r.bottom, GetCharacterHeight(FS_NORMAL)),
2676 GetString(v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT : STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS,
2677 v->GetServiceInterval(), STR_VEHICLE_DETAILS_LAST_SERVICE_DATE, v->date_of_last_service));
2678 break;
2679 }
2680 }
2681 }
2682
2684 void OnPaint() override
2685 {
2686 const Vehicle *v = Vehicle::Get(this->window_number);
2687
2688 if (v->type == VEH_TRAIN) {
2689 this->LowerWidget(WID_VD_DETAILS_CARGO_CARRIED + this->tab);
2690 this->vscroll->SetCount(GetTrainDetailsWndVScroll(v->index, this->tab));
2691 }
2692
2693 /* Disable service-scroller when interval is set to disabled */
2694 this->SetWidgetsDisabledState(!IsVehicleServiceIntervalEnabled(v->type, v->owner),
2695 WID_VD_INCREASE_SERVICING_INTERVAL,
2696 WID_VD_DECREASE_SERVICING_INTERVAL);
2697
2698 StringID str =
2699 !v->ServiceIntervalIsCustom() ? STR_VEHICLE_DETAILS_DEFAULT :
2700 v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_PERCENT :
2701 TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_DETAILS_MINUTES : STR_VEHICLE_DETAILS_DAYS;
2702 this->GetWidget<NWidgetCore>(WID_VD_SERVICE_INTERVAL_DROPDOWN)->SetString(str);
2703 this->SetWidgetDisabledState(WID_VD_SERVICE_INTERVAL_DROPDOWN, v->owner != _local_company);
2704
2705 this->DrawWidgets();
2706 }
2707
2708 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
2709 {
2710 switch (widget) {
2711 case WID_VD_INCREASE_SERVICING_INTERVAL: // increase int
2712 case WID_VD_DECREASE_SERVICING_INTERVAL: { // decrease int
2713 const Vehicle *v = Vehicle::Get(this->window_number);
2714 int mod;
2715 if (!v->ServiceIntervalIsPercent() && TimerGameEconomy::UsingWallclockUnits()) {
2716 mod = _ctrl_pressed ? 1 : 5;
2717 } else {
2718 mod = _ctrl_pressed ? 5 : 10;
2719 }
2720
2721 mod = (widget == WID_VD_DECREASE_SERVICING_INTERVAL) ? -mod : mod;
2722 mod = GetServiceIntervalClamped(mod + v->GetServiceInterval(), v->ServiceIntervalIsPercent());
2723 if (mod == v->GetServiceInterval()) return;
2724
2725 Command<CMD_CHANGE_SERVICE_INT>::Post(STR_ERROR_CAN_T_CHANGE_SERVICING, v->index, mod, true, v->ServiceIntervalIsPercent());
2726 break;
2727 }
2728
2729 case WID_VD_SERVICE_INTERVAL_DROPDOWN: {
2730 const Vehicle *v = Vehicle::Get(this->window_number);
2731 ShowDropDownMenu(this,
2732 TimerGameEconomy::UsingWallclockUnits() ? _service_interval_dropdown_wallclock : _service_interval_dropdown_calendar,
2733 v->ServiceIntervalIsCustom() ? (v->ServiceIntervalIsPercent() ? 2 : 1) : 0, widget, 0, 0);
2734 break;
2735 }
2736
2737 case WID_VD_DETAILS_CARGO_CARRIED:
2738 case WID_VD_DETAILS_TRAIN_VEHICLES:
2739 case WID_VD_DETAILS_CAPACITY_OF_EACH:
2740 case WID_VD_DETAILS_TOTAL_CARGO:
2741 this->SetWidgetsLoweredState(false,
2742 WID_VD_DETAILS_CARGO_CARRIED,
2743 WID_VD_DETAILS_TRAIN_VEHICLES,
2744 WID_VD_DETAILS_CAPACITY_OF_EACH,
2745 WID_VD_DETAILS_TOTAL_CARGO);
2746
2747 this->tab = (TrainDetailsWindowTabs)(widget - WID_VD_DETAILS_CARGO_CARRIED);
2748 this->SetDirty();
2749 break;
2750 }
2751 }
2752
2753 bool OnTooltip([[maybe_unused]] Point pt, WidgetID widget, TooltipCloseCondition close_cond) override
2754 {
2755 if (widget == WID_VD_INCREASE_SERVICING_INTERVAL || widget == WID_VD_DECREASE_SERVICING_INTERVAL) {
2756 const Vehicle *v = Vehicle::Get(this->window_number);
2757 StringID tool_tip;
2758 if (v->ServiceIntervalIsPercent()) {
2759 tool_tip = widget == WID_VD_INCREASE_SERVICING_INTERVAL ? STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP_PERCENT : STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP_PERCENT;
2760 } else if (TimerGameEconomy::UsingWallclockUnits()) {
2761 tool_tip = widget == WID_VD_INCREASE_SERVICING_INTERVAL ? STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP_MINUTES : STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP_MINUTES;
2762 } else {
2763 tool_tip = widget == WID_VD_INCREASE_SERVICING_INTERVAL ? STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP_DAYS : STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP_DAYS;
2764 }
2765 GuiShowTooltips(this, GetEncodedString(tool_tip), close_cond);
2766 return true;
2767 }
2768
2769 return false;
2770 }
2771
2772 void OnDropdownSelect(WidgetID widget, int index, int) override
2773 {
2774 switch (widget) {
2775 case WID_VD_SERVICE_INTERVAL_DROPDOWN: {
2776 const Vehicle *v = Vehicle::Get(this->window_number);
2777 bool iscustom = index != 0;
2778 bool ispercent = iscustom ? (index == 2) : Company::Get(v->owner)->settings.vehicle.servint_ispercent;
2779 uint16_t interval = GetServiceIntervalClamped(v->GetServiceInterval(), ispercent);
2780 Command<CMD_CHANGE_SERVICE_INT>::Post(STR_ERROR_CAN_T_CHANGE_SERVICING, v->index, interval, iscustom, ispercent);
2781 break;
2782 }
2783 }
2784 }
2785
2786 void OnResize() override
2787 {
2788 NWidgetCore *nwi = this->GetWidget<NWidgetCore>(WID_VD_MATRIX);
2789 if (nwi != nullptr) {
2790 this->vscroll->SetCapacityFromWidget(this, WID_VD_MATRIX);
2791 }
2792 }
2793};
2794
2796 static WindowDesc _train_vehicle_details_desc(
2797 WDP_AUTO, "view_vehicle_details_train", 405, 178,
2798 WC_VEHICLE_DETAILS, WC_VEHICLE_VIEW,
2799 {},
2800 _nested_train_vehicle_details_widgets
2801);
2802
2804 static WindowDesc _nontrain_vehicle_details_desc(
2805 WDP_AUTO, "view_vehicle_details", 405, 113,
2806 WC_VEHICLE_DETAILS, WC_VEHICLE_VIEW,
2807 {},
2808 _nested_nontrain_vehicle_details_widgets
2809);
2810
2812 static void ShowVehicleDetailsWindow(const Vehicle *v)
2813{
2814 CloseWindowById(WC_VEHICLE_ORDERS, v->index, false);
2815 CloseWindowById(WC_VEHICLE_TIMETABLE, v->index, false);
2816 AllocateWindowDescFront<VehicleDetailsWindow>((v->type == VEH_TRAIN) ? _train_vehicle_details_desc : _nontrain_vehicle_details_desc, v->index);
2817}
2818
2819
2820/* Unified vehicle GUI - Vehicle View Window */
2821
2823 static constexpr std::initializer_list<NWidgetPart> _nested_vehicle_view_widgets = {
2824 NWidget(NWID_HORIZONTAL),
2825 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
2826 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_RENAME), SetAspect(WidgetDimensions::ASPECT_RENAME), SetSpriteTip(SPR_RENAME),
2827 NWidget(WWT_CAPTION, COLOUR_GREY, WID_VV_CAPTION),
2828 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_LOCATION), SetAspect(WidgetDimensions::ASPECT_LOCATION), SetSpriteTip(SPR_GOTO_LOCATION),
2829 NWidget(WWT_DEBUGBOX, COLOUR_GREY),
2830 NWidget(WWT_SHADEBOX, COLOUR_GREY),
2831 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
2832 NWidget(WWT_STICKYBOX, COLOUR_GREY),
2833 EndContainer(),
2834 NWidget(NWID_HORIZONTAL),
2835 NWidget(WWT_PANEL, COLOUR_GREY),
2836 NWidget(WWT_INSET, COLOUR_GREY), SetPadding(2, 2, 2, 2),
2837 NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_VV_VIEWPORT), SetMinimalSize(226, 84), SetResize(1, 1),
2838 EndContainer(),
2839 EndContainer(),
2840 NWidget(NWID_VERTICAL),
2841 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VV_SELECT_DEPOT_CLONE),
2842 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_GOTO_DEPOT), SetMinimalSize(18, 18), SetSpriteTip(SPR_EMPTY /* filled later */),
2843 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_CLONE), SetMinimalSize(18, 18), SetSpriteTip(SPR_EMPTY /* filled later */),
2844 EndContainer(),
2845 /* For trains only, 'ignore signal' button. */
2846 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VV_FORCE_PROCEED_SEL),
2847 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_FORCE_PROCEED), SetMinimalSize(18, 18),
2848 SetSpriteTip(SPR_IGNORE_SIGNALS, STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP),
2849 EndContainer(),
2850 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VV_SELECT_REFIT_TURN),
2851 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_REFIT), SetMinimalSize(18, 18), SetSpriteTip(SPR_REFIT_VEHICLE),
2852 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_TURN_AROUND), SetMinimalSize(18, 18),
2853 SetSpriteTip(SPR_FORCE_VEHICLE_TURN, STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP),
2854 EndContainer(),
2855 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_SHOW_ORDERS), SetMinimalSize(18, 18), SetSpriteTip(SPR_SHOW_ORDERS),
2856 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_SHOW_DETAILS), SetMinimalSize(18, 18), SetSpriteTip(SPR_SHOW_VEHICLE_DETAILS),
2857 NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(18, 0), SetResize(0, 1), EndContainer(),
2858 EndContainer(),
2859 EndContainer(),
2860 NWidget(NWID_HORIZONTAL),
2861 NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_VV_START_STOP), SetResize(1, 0), SetFill(1, 0),
2862 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_ORDER_LOCATION), SetAspect(WidgetDimensions::ASPECT_LOCATION), SetSpriteTip(SPR_GOTO_LOCATION, STR_VEHICLE_VIEW_ORDER_LOCATION_TOOLTIP),
2863 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
2864 EndContainer(),
2865};
2866
2867/* Just to make sure, nobody has changed the vehicle type constants, as we are
2868 using them for array indexing in a number of places here. */
2869static_assert(VEH_TRAIN == 0);
2870static_assert(VEH_ROAD == 1);
2871static_assert(VEH_SHIP == 2);
2872static_assert(VEH_AIRCRAFT == 3);
2873
2875 static const ZoomLevel _vehicle_view_zoom_levels[] = {
2876 ZoomLevel::Train,
2877 ZoomLevel::RoadVehicle,
2878 ZoomLevel::Ship,
2879 ZoomLevel::Aircraft,
2880};
2881
2882/* Constants for geometry of vehicle view viewport */
2883static const int VV_INITIAL_VIEWPORT_WIDTH = 226;
2884static const int VV_INITIAL_VIEWPORT_HEIGHT = 84;
2885static const int VV_INITIAL_VIEWPORT_HEIGHT_TRAIN = 102;
2886
2888 enum VehicleCommandTranslation : uint8_t {
2889 VCT_CMD_START_STOP = 0,
2890 VCT_CMD_CLONE_VEH,
2891 VCT_CMD_TURN_AROUND,
2892};
2893
2895 static const StringID _vehicle_msg_translation_table[][4] = {
2896 { // VCT_CMD_START_STOP
2897 STR_ERROR_CAN_T_STOP_START_TRAIN,
2898 STR_ERROR_CAN_T_STOP_START_ROAD_VEHICLE,
2899 STR_ERROR_CAN_T_STOP_START_SHIP,
2900 STR_ERROR_CAN_T_STOP_START_AIRCRAFT
2901 },
2902 { // VCT_CMD_CLONE_VEH
2903 STR_ERROR_CAN_T_BUY_TRAIN,
2904 STR_ERROR_CAN_T_BUY_ROAD_VEHICLE,
2905 STR_ERROR_CAN_T_BUY_SHIP,
2906 STR_ERROR_CAN_T_BUY_AIRCRAFT
2907 },
2908 { // VCT_CMD_TURN_AROUND
2909 STR_ERROR_CAN_T_REVERSE_DIRECTION_TRAIN,
2910 STR_ERROR_CAN_T_MAKE_ROAD_VEHICLE_TURN,
2911 INVALID_STRING_ID, // invalid for ships
2912 INVALID_STRING_ID // invalid for aircraft
2913 },
2914};
2915
2921 void CcStartStopVehicle(Commands, const CommandCost &result, VehicleID veh_id, bool)
2922{
2923 if (result.Failed()) return;
2924
2925 const Vehicle *v = Vehicle::GetIfValid(veh_id);
2926 if (v == nullptr || !v->IsPrimaryVehicle() || v->owner != _local_company) return;
2927
2928 StringID msg = v->vehstatus.Test(VehState::Stopped) ? STR_VEHICLE_COMMAND_STOPPED : STR_VEHICLE_COMMAND_STARTED;
2929 Point pt = RemapCoords(v->x_pos, v->y_pos, v->z_pos);
2930 AddTextEffect(GetEncodedString(msg), pt.x, pt.y, Ticks::DAY_TICKS, TE_RISING);
2931}
2932
2938 void StartStopVehicle(const Vehicle *v, bool texteffect)
2939{
2940 assert(v->IsPrimaryVehicle());
2941 Command<CMD_START_STOP_VEHICLE>::Post(_vehicle_msg_translation_table[VCT_CMD_START_STOP][v->type], texteffect ? CcStartStopVehicle : nullptr, v->tile, v->index, false);
2942}
2943
2945 static bool IsVehicleRefittable(const Vehicle *v)
2946{
2947 if (!v->IsStoppedInDepot()) return false;
2948
2949 do {
2950 if (IsEngineRefittable(v->engine_type)) return true;
2951 } while (v->IsGroundVehicle() && (v = v->Next()) != nullptr);
2952
2953 return false;
2954}
2955
2957 struct VehicleViewWindow : Window {
2958private:
2960 enum PlaneSelections : uint8_t {
2961 SEL_DC_GOTO_DEPOT,
2962 SEL_DC_CLONE,
2963
2964 SEL_RT_REFIT,
2965 SEL_RT_TURN_AROUND,
2966
2967 SEL_DC_BASEPLANE = SEL_DC_GOTO_DEPOT,
2968 SEL_RT_BASEPLANE = SEL_RT_REFIT,
2969 };
2970 bool mouse_over_start_stop = false;
2971
2976 void SelectPlane(PlaneSelections plane)
2977 {
2978 switch (plane) {
2979 case SEL_DC_GOTO_DEPOT:
2980 case SEL_DC_CLONE:
2981 this->GetWidget<NWidgetStacked>(WID_VV_SELECT_DEPOT_CLONE)->SetDisplayedPlane(plane - SEL_DC_BASEPLANE);
2982 break;
2983
2984 case SEL_RT_REFIT:
2985 case SEL_RT_TURN_AROUND:
2986 this->GetWidget<NWidgetStacked>(WID_VV_SELECT_REFIT_TURN)->SetDisplayedPlane(plane - SEL_RT_BASEPLANE);
2987 break;
2988
2989 default:
2990 NOT_REACHED();
2991 }
2992 }
2993
2994public:
2995 VehicleViewWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc)
2996 {
2997 this->flags.Set(WindowFlag::DisableVpScroll);
2998 this->CreateNestedTree();
2999
3000 /* Sprites for the 'send to depot' button indexed by vehicle type. */
3001 static const SpriteID vehicle_view_goto_depot_sprites[] = {
3002 SPR_SEND_TRAIN_TODEPOT,
3003 SPR_SEND_ROADVEH_TODEPOT,
3004 SPR_SEND_SHIP_TODEPOT,
3005 SPR_SEND_AIRCRAFT_TODEPOT,
3006 };
3007 const Vehicle *v = Vehicle::Get(window_number);
3008 this->GetWidget<NWidgetCore>(WID_VV_GOTO_DEPOT)->SetSprite(vehicle_view_goto_depot_sprites[v->type]);
3009
3010 /* Sprites for the 'clone vehicle' button indexed by vehicle type. */
3011 static const SpriteID vehicle_view_clone_sprites[] = {
3012 SPR_CLONE_TRAIN,
3013 SPR_CLONE_ROADVEH,
3014 SPR_CLONE_SHIP,
3015 SPR_CLONE_AIRCRAFT,
3016 };
3017 this->GetWidget<NWidgetCore>(WID_VV_CLONE)->SetSprite(vehicle_view_clone_sprites[v->type]);
3018
3019 switch (v->type) {
3020 case VEH_TRAIN:
3021 this->GetWidget<NWidgetCore>(WID_VV_TURN_AROUND)->SetToolTip(STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP);
3022 this->GetWidget<NWidgetStacked>(WID_VV_FORCE_PROCEED_SEL)->SetDisplayedPlane(0);
3023 break;
3024
3025 case VEH_ROAD:
3026 this->GetWidget<NWidgetStacked>(WID_VV_FORCE_PROCEED_SEL)->SetDisplayedPlane(SZSP_NONE);
3027 break;
3028
3029 case VEH_SHIP:
3030 case VEH_AIRCRAFT:
3031 this->GetWidget<NWidgetStacked>(WID_VV_FORCE_PROCEED_SEL)->SetDisplayedPlane(SZSP_NONE);
3032 this->SelectPlane(SEL_RT_REFIT);
3033 break;
3034
3035 default: NOT_REACHED();
3036 }
3037 this->FinishInitNested(window_number);
3038 this->owner = v->owner;
3039 this->GetWidget<NWidgetViewport>(WID_VV_VIEWPORT)->InitializeViewport(this, static_cast<VehicleID>(this->window_number), ScaleZoomGUI(_vehicle_view_zoom_levels[v->type]));
3040
3041 this->GetWidget<NWidgetCore>(WID_VV_START_STOP)->SetToolTip(STR_VEHICLE_VIEW_TRAIN_STATUS_START_STOP_TOOLTIP + v->type);
3042 this->GetWidget<NWidgetCore>(WID_VV_RENAME)->SetToolTip(STR_VEHICLE_DETAILS_TRAIN_RENAME + v->type);
3043 this->GetWidget<NWidgetCore>(WID_VV_LOCATION)->SetToolTip(STR_VEHICLE_VIEW_TRAIN_CENTER_TOOLTIP + v->type);
3044 this->GetWidget<NWidgetCore>(WID_VV_REFIT)->SetToolTip(STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP + v->type);
3045 this->GetWidget<NWidgetCore>(WID_VV_GOTO_DEPOT)->SetToolTip(STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP + v->type);
3046 this->GetWidget<NWidgetCore>(WID_VV_SHOW_ORDERS)->SetToolTip(STR_VEHICLE_VIEW_TRAIN_ORDERS_TOOLTIP + v->type);
3047 this->GetWidget<NWidgetCore>(WID_VV_SHOW_DETAILS)->SetToolTip(STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP + v->type);
3048 this->GetWidget<NWidgetCore>(WID_VV_CLONE)->SetToolTip(STR_VEHICLE_VIEW_CLONE_TRAIN_INFO + v->type);
3049
3050 this->UpdateButtonStatus();
3051 }
3052
3053 void Close([[maybe_unused]] int data = 0) override
3054 {
3055 CloseWindowById(WC_VEHICLE_ORDERS, this->window_number, false);
3056 CloseWindowById(WC_VEHICLE_REFIT, this->window_number, false);
3057 CloseWindowById(WC_VEHICLE_DETAILS, this->window_number, false);
3058 CloseWindowById(WC_VEHICLE_TIMETABLE, this->window_number, false);
3059 this->Window::Close();
3060 }
3061
3062 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
3063 {
3064 const Vehicle *v = Vehicle::Get(this->window_number);
3065 switch (widget) {
3066 case WID_VV_START_STOP:
3067 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;
3068 break;
3069
3070 case WID_VV_FORCE_PROCEED:
3071 if (v->type != VEH_TRAIN) {
3072 size.height = 0;
3073 size.width = 0;
3074 }
3075 break;
3076
3077 case WID_VV_VIEWPORT:
3078 size.width = VV_INITIAL_VIEWPORT_WIDTH;
3079 size.height = (v->type == VEH_TRAIN) ? VV_INITIAL_VIEWPORT_HEIGHT_TRAIN : VV_INITIAL_VIEWPORT_HEIGHT;
3080 break;
3081 }
3082 }
3083
3084 void OnPaint() override
3085 {
3086 const Vehicle *v = Vehicle::Get(this->window_number);
3087 bool is_localcompany = v->owner == _local_company;
3088 bool refittable_and_stopped_in_depot = IsVehicleRefittable(v);
3089
3090 this->SetWidgetDisabledState(WID_VV_RENAME, !is_localcompany);
3091 this->SetWidgetDisabledState(WID_VV_GOTO_DEPOT, !is_localcompany);
3092 this->SetWidgetDisabledState(WID_VV_REFIT, !refittable_and_stopped_in_depot || !is_localcompany);
3093 this->SetWidgetDisabledState(WID_VV_CLONE, !is_localcompany);
3094
3095 if (v->type == VEH_TRAIN) {
3096 this->SetWidgetLoweredState(WID_VV_FORCE_PROCEED, Train::From(v)->force_proceed == TFP_SIGNAL);
3097 this->SetWidgetDisabledState(WID_VV_FORCE_PROCEED, !is_localcompany);
3098 }
3099
3100 if (v->type == VEH_TRAIN || v->type == VEH_ROAD) {
3101 this->SetWidgetDisabledState(WID_VV_TURN_AROUND, !is_localcompany);
3102 }
3103
3104 this->SetWidgetDisabledState(WID_VV_ORDER_LOCATION, v->current_order.GetLocation(v) == INVALID_TILE);
3105
3106 const Window *mainwindow = GetMainWindow();
3107 if (mainwindow->viewport->follow_vehicle == v->index) {
3108 this->LowerWidget(WID_VV_LOCATION);
3109 }
3110
3111 this->DrawWidgets();
3112 }
3113
3114 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
3115 {
3116 if (widget != WID_VV_CAPTION) return this->Window::GetWidgetString(widget, stringid);
3117
3118 const Vehicle *v = Vehicle::Get(this->window_number);
3119 return GetString(STR_VEHICLE_VIEW_CAPTION, v->index);
3120 }
3121
3122 std::string GetVehicleStatusString(const Vehicle *v, TextColour &text_colour) const
3123 {
3124 text_colour = TC_BLACK;
3125
3126 if (v->vehstatus.Test(VehState::Crashed)) return GetString(STR_VEHICLE_STATUS_CRASHED);
3127
3128 if (v->type != VEH_AIRCRAFT && v->breakdown_ctr == 1) return GetString(STR_VEHICLE_STATUS_BROKEN_DOWN);
3129
3130 if (v->vehstatus.Test(VehState::Stopped) && (!mouse_over_start_stop || v->IsStoppedInDepot())) {
3131 if (v->type != VEH_TRAIN) return GetString(STR_VEHICLE_STATUS_STOPPED);
3132 if (v->cur_speed != 0) return GetString(STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL, PackVelocity(v->GetDisplaySpeed(), v->type));
3133 if (Train::From(v)->gcache.cached_power == 0) return GetString(STR_VEHICLE_STATUS_TRAIN_NO_POWER);
3134 return GetString(STR_VEHICLE_STATUS_STOPPED);
3135 }
3136
3137 if (v->IsInDepot() && v->IsWaitingForUnbunching()) return GetString(STR_VEHICLE_STATUS_WAITING_UNBUNCHING);
3138
3139 if (v->type == VEH_TRAIN && Train::From(v)->flags.Test(VehicleRailFlag::Stuck) && !v->current_order.IsType(OT_LOADING)) return GetString(STR_VEHICLE_STATUS_TRAIN_STUCK);
3140
3141 if (v->type == VEH_AIRCRAFT && HasBit(Aircraft::From(v)->flags, VAF_DEST_TOO_FAR) && !v->current_order.IsType(OT_LOADING)) return GetString(STR_VEHICLE_STATUS_AIRCRAFT_TOO_FAR);
3142
3143 /* Vehicle is in a "normal" state, show current order. */
3144 if (mouse_over_start_stop) {
3145 if (v->vehstatus.Test(VehState::Stopped)) {
3146 text_colour = TC_RED | TC_FORCED;
3147 } else if (v->type == VEH_TRAIN && Train::From(v)->flags.Test(VehicleRailFlag::Stuck) && !v->current_order.IsType(OT_LOADING)) {
3148 text_colour = TC_ORANGE | TC_FORCED;
3149 }
3150 }
3151
3152 switch (v->current_order.GetType()) {
3153 case OT_GOTO_STATION:
3154 return GetString(v->vehicle_flags.Test(VehicleFlag::PathfinderLost) ? STR_VEHICLE_STATUS_CANNOT_REACH_STATION_VEL : STR_VEHICLE_STATUS_HEADING_FOR_STATION_VEL,
3155 v->current_order.GetDestination(), PackVelocity(v->GetDisplaySpeed(), v->type));
3156
3157 case OT_GOTO_DEPOT: {
3158 /* This case *only* happens when multiple nearest depot orders
3159 * follow each other (including an order list only one order: a
3160 * nearest depot order) and there are no reachable depots.
3161 * It is primarily to guard for the case that there is no
3162 * depot with index 0, which would be used as fallback for
3163 * evaluating the string in the status bar. */
3164 if (v->current_order.GetDestination() == DepotID::Invalid()) return {};
3165
3166 auto params = MakeParameters(v->type, v->current_order.GetDestination(), PackVelocity(v->GetDisplaySpeed(), v->type));
3167 if (v->current_order.GetDepotActionType().Test(OrderDepotActionFlag::Halt)) {
3168 return GetStringWithArgs(v->vehicle_flags.Test(VehicleFlag::PathfinderLost) ? STR_VEHICLE_STATUS_CANNOT_REACH_DEPOT_VEL : STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_VEL, params);
3169 }
3170
3171 if (v->current_order.GetDepotActionType().Test(OrderDepotActionFlag::Unbunch)) {
3172 return GetStringWithArgs(v->vehicle_flags.Test(VehicleFlag::PathfinderLost) ? STR_VEHICLE_STATUS_CANNOT_REACH_DEPOT_SERVICE_VEL : STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_UNBUNCH_VEL, params);
3173 }
3174
3175 return GetStringWithArgs(v->vehicle_flags.Test(VehicleFlag::PathfinderLost) ? STR_VEHICLE_STATUS_CANNOT_REACH_DEPOT_SERVICE_VEL : STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_SERVICE_VEL, params);
3176 }
3177
3178 case OT_LOADING:
3179 return GetString(STR_VEHICLE_STATUS_LOADING_UNLOADING);
3180
3181 case OT_GOTO_WAYPOINT:
3182 assert(v->type == VEH_TRAIN || v->type == VEH_ROAD || v->type == VEH_SHIP);
3183 return GetString(v->vehicle_flags.Test(VehicleFlag::PathfinderLost) ? STR_VEHICLE_STATUS_CANNOT_REACH_WAYPOINT_VEL : STR_VEHICLE_STATUS_HEADING_FOR_WAYPOINT_VEL,
3184 v->current_order.GetDestination(),PackVelocity(v->GetDisplaySpeed(), v->type));
3185
3186 case OT_LEAVESTATION:
3187 if (v->type != VEH_AIRCRAFT) {
3188 return GetString(STR_VEHICLE_STATUS_LEAVING);
3189 }
3190 [[fallthrough]];
3191
3192 default:
3193 if (v->GetNumManualOrders() == 0) {
3194 return GetString(STR_VEHICLE_STATUS_NO_ORDERS_VEL, PackVelocity(v->GetDisplaySpeed(), v->type));
3195 }
3196
3197 return {};
3198 }
3199 }
3200
3201 void DrawWidget(const Rect &r, WidgetID widget) const override
3202 {
3203 if (widget != WID_VV_START_STOP) return;
3204
3205 /* Draw the flag plus orders. */
3206 bool rtl = (_current_text_dir == TD_RTL);
3207 uint icon_width = std::max({GetScaledSpriteSize(SPR_WARNING_SIGN).width, GetScaledSpriteSize(SPR_FLAG_VEH_STOPPED).width, GetScaledSpriteSize(SPR_FLAG_VEH_RUNNING).width});
3208 Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
3209
3210 const Vehicle *v = Vehicle::Get(this->window_number);
3211 SpriteID image = v->vehstatus.Test(VehState::Stopped) ? SPR_FLAG_VEH_STOPPED : (v->vehicle_flags.Test(VehicleFlag::PathfinderLost)) ? SPR_WARNING_SIGN : SPR_FLAG_VEH_RUNNING;
3212 DrawSpriteIgnorePadding(image, PAL_NONE, tr.WithWidth(icon_width, rtl), SA_CENTER);
3213
3214 tr = tr.Indent(icon_width + WidgetDimensions::scaled.imgbtn.Horizontal(), rtl);
3215
3216 TextColour text_colour = TC_FROMSTRING;
3217 std::string str = GetVehicleStatusString(v, text_colour);
3218 DrawString(tr.left, tr.right, CentreBounds(tr.top, tr.bottom, GetCharacterHeight(FS_NORMAL)), str, text_colour, SA_HOR_CENTER);
3219 }
3220
3221 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
3222 {
3223 const Vehicle *v = Vehicle::Get(this->window_number);
3224
3225 switch (widget) {
3226 case WID_VV_RENAME: { // rename
3227 ShowQueryString(GetString(STR_VEHICLE_NAME, v->index), STR_QUERY_RENAME_TRAIN_CAPTION + v->type,
3228 MAX_LENGTH_VEHICLE_NAME_CHARS, this, CS_ALPHANUMERAL, {QueryStringFlag::EnableDefault, QueryStringFlag::LengthIsInChars});
3229 break;
3230 }
3231
3232 case WID_VV_START_STOP: // start stop
3233 StartStopVehicle(v, false);
3234 break;
3235
3236 case WID_VV_ORDER_LOCATION: {
3237 /* Scroll to current order destination */
3238 TileIndex tile = v->current_order.GetLocation(v);
3239 if (tile == INVALID_TILE) break;
3240
3241 if (_ctrl_pressed) {
3242 ShowExtraViewportWindow(tile);
3243 } else {
3244 ScrollMainWindowToTile(tile);
3245 }
3246 break;
3247 }
3248
3249 case WID_VV_LOCATION: // center main view
3250 if (_ctrl_pressed) {
3251 ShowExtraViewportWindow(TileVirtXY(v->x_pos, v->y_pos));
3252 } else {
3253 const Window *mainwindow = GetMainWindow();
3254 if (click_count > 1) {
3255 /* main window 'follows' vehicle */
3256 mainwindow->viewport->follow_vehicle = v->index;
3257 } else {
3258 if (mainwindow->viewport->follow_vehicle == v->index) mainwindow->viewport->follow_vehicle = VehicleID::Invalid();
3259 ScrollMainWindowTo(v->x_pos, v->y_pos, v->z_pos);
3260 }
3261 }
3262 break;
3263
3264 case WID_VV_GOTO_DEPOT: // goto hangar
3265 Command<CMD_SEND_VEHICLE_TO_DEPOT>::Post(GetCmdSendToDepotMsg(v), v->index, _ctrl_pressed ? DepotCommandFlag::Service : DepotCommandFlags{}, {});
3266 break;
3267 case WID_VV_REFIT: // refit
3268 ShowVehicleRefitWindow(v, INVALID_VEH_ORDER_ID, this);
3269 break;
3270 case WID_VV_SHOW_ORDERS: // show orders
3271 if (_ctrl_pressed) {
3272 ShowTimetableWindow(v);
3273 } else {
3274 ShowOrdersWindow(v);
3275 }
3276 break;
3277 case WID_VV_SHOW_DETAILS: // show details
3278 if (_ctrl_pressed) {
3279 ShowCompanyGroupForVehicle(v);
3280 } else {
3281 ShowVehicleDetailsWindow(v);
3282 }
3283 break;
3284 case WID_VV_CLONE: // clone vehicle
3285 /* Suppress the vehicle GUI when share-cloning.
3286 * There is no point to it except for starting the vehicle.
3287 * For starting the vehicle the player has to open the depot GUI, which is
3288 * most likely already open, but is also visible in the vehicle viewport. */
3289 Command<CMD_CLONE_VEHICLE>::Post(_vehicle_msg_translation_table[VCT_CMD_CLONE_VEH][v->type],
3290 _ctrl_pressed ? nullptr : CcCloneVehicle,
3291 v->tile, v->index, _ctrl_pressed);
3292 break;
3293 case WID_VV_TURN_AROUND: // turn around
3294 assert(v->IsGroundVehicle());
3295 if (v->type == VEH_ROAD) {
3296 Command<CMD_TURN_ROADVEH>::Post(_vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index);
3297 } else {
3298 Command<CMD_REVERSE_TRAIN_DIRECTION>::Post(_vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, false);
3299 }
3300 break;
3301 case WID_VV_FORCE_PROCEED: // force proceed
3302 assert(v->type == VEH_TRAIN);
3303 Command<CMD_FORCE_TRAIN_PROCEED>::Post(STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL, v->tile, v->index);
3304 break;
3305 }
3306 }
3307
3308 EventState OnHotkey(int hotkey) override
3309 {
3310 /* If the hotkey is not for any widget in the UI (i.e. for honking) */
3311 if (hotkey == WID_VV_HONK_HORN) {
3312 const Window *mainwindow = GetMainWindow();
3313 const Vehicle *v = Vehicle::Get(window_number);
3314 /* Only play the sound if we're following this vehicle */
3315 if (mainwindow->viewport->follow_vehicle == v->index) {
3316 v->PlayLeaveStationSound(true);
3317 }
3318 }
3319 return Window::OnHotkey(hotkey);
3320 }
3321
3322 void OnQueryTextFinished(std::optional<std::string> str) override
3323 {
3324 if (!str.has_value()) return;
3325
3326 Command<CMD_RENAME_VEHICLE>::Post(STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type, static_cast<VehicleID>(this->window_number), *str);
3327 }
3328
3329 void OnMouseOver([[maybe_unused]] Point pt, WidgetID widget) override
3330 {
3331 bool start_stop = widget == WID_VV_START_STOP;
3332 if (start_stop != mouse_over_start_stop) {
3333 mouse_over_start_stop = start_stop;
3334 this->SetWidgetDirty(WID_VV_START_STOP);
3335 }
3336 }
3337
3338 void OnMouseWheel(int wheel, WidgetID widget) override
3339 {
3340 if (widget != WID_VV_VIEWPORT) return;
3341 if (_settings_client.gui.scrollwheel_scrolling != SWS_OFF) {
3342 DoZoomInOutWindow(wheel < 0 ? ZOOM_IN : ZOOM_OUT, this);
3343 }
3344 }
3345
3346 void OnResize() override
3347 {
3348 if (this->viewport != nullptr) {
3349 NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_VV_VIEWPORT);
3350 nvp->UpdateViewportCoordinates(this);
3351 }
3352 }
3353
3354 void UpdateButtonStatus()
3355 {
3356 const Vehicle *v = Vehicle::Get(this->window_number);
3357 bool veh_stopped = v->IsStoppedInDepot();
3358
3359 /* Widget WID_VV_GOTO_DEPOT must be hidden if the vehicle is already stopped in depot.
3360 * Widget WID_VV_CLONE_VEH should then be shown, since cloning is allowed only while in depot and stopped.
3361 */
3362 PlaneSelections plane = veh_stopped ? SEL_DC_CLONE : SEL_DC_GOTO_DEPOT;
3363 NWidgetStacked *nwi = this->GetWidget<NWidgetStacked>(WID_VV_SELECT_DEPOT_CLONE); // Selection widget 'send to depot' / 'clone'.
3364 if (nwi->shown_plane + SEL_DC_BASEPLANE != plane) {
3365 this->SelectPlane(plane);
3366 this->SetWidgetDirty(WID_VV_SELECT_DEPOT_CLONE);
3367 }
3368 /* The same system applies to widget WID_VV_REFIT_VEH and VVW_WIDGET_TURN_AROUND.*/
3369 if (v->IsGroundVehicle()) {
3370 plane = veh_stopped ? SEL_RT_REFIT : SEL_RT_TURN_AROUND;
3371 nwi = this->GetWidget<NWidgetStacked>(WID_VV_SELECT_REFIT_TURN);
3372 if (nwi->shown_plane + SEL_RT_BASEPLANE != plane) {
3373 this->SelectPlane(plane);
3374 this->SetWidgetDirty(WID_VV_SELECT_REFIT_TURN);
3375 }
3376 }
3377 }
3378
3384 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
3385 {
3386 if (data == VIWD_AUTOREPLACE) {
3387 /* Autoreplace replaced the vehicle.
3388 * Nothing to do for this window. */
3389 return;
3390 }
3391
3392 this->UpdateButtonStatus();
3393 }
3394
3395 bool IsNewGRFInspectable() const override
3396 {
3397 return ::IsNewGRFInspectable(GetGrfSpecFeature(Vehicle::Get(this->window_number)->type), this->window_number);
3398 }
3399
3400 void ShowNewGRFInspectWindow() const override
3401 {
3402 ::ShowNewGRFInspectWindow(GetGrfSpecFeature(Vehicle::Get(this->window_number)->type), this->window_number);
3403 }
3404
3405 static inline HotkeyList hotkeys{"vehicleview", {
3406 Hotkey('H', "honk", WID_VV_HONK_HORN),
3407 }};
3408};
3409
3411 static WindowDesc _vehicle_view_desc(
3412 WDP_AUTO, "view_vehicle", 250, 116,
3413 WC_VEHICLE_VIEW, WC_NONE,
3414 {},
3415 _nested_vehicle_view_widgets,
3416 &VehicleViewWindow::hotkeys
3417);
3418
3423 static WindowDesc _train_view_desc(
3424 WDP_AUTO, "view_vehicle_train", 250, 134,
3425 WC_VEHICLE_VIEW, WC_NONE,
3426 {},
3427 _nested_vehicle_view_widgets,
3428 &VehicleViewWindow::hotkeys
3429);
3430
3432 void ShowVehicleViewWindow(const Vehicle *v)
3433{
3434 AllocateWindowDescFront<VehicleViewWindow>((v->type == VEH_TRAIN) ? _train_view_desc : _vehicle_view_desc, v->index);
3435}
3436
3442 bool VehicleClicked(const Vehicle *v)
3443{
3444 assert(v != nullptr);
3445 if (!(_thd.place_mode & HT_VEHICLE)) return false;
3446
3447 v = v->First();
3448 if (!v->IsPrimaryVehicle()) return false;
3449
3450 return _thd.GetCallbackWnd()->OnVehicleSelect(v);
3451}
3452
3459 bool VehicleClicked(VehicleList::const_iterator begin, VehicleList::const_iterator end)
3460{
3461 assert(begin != end);
3462 if (!(_thd.place_mode & HT_VEHICLE)) return false;
3463
3464 /* If there is only one vehicle in the group, act as if we clicked a single vehicle */
3465 if (begin + 1 == end) return _thd.GetCallbackWnd()->OnVehicleSelect(*begin);
3466
3467 return _thd.GetCallbackWnd()->OnVehicleSelect(begin, end);
3468}
3469
3475 bool VehicleClicked(const GUIVehicleGroup &vehgroup)
3476{
3477 return VehicleClicked(vehgroup.vehicles_begin, vehgroup.vehicles_end);
3478}
3479
3480void StopGlobalFollowVehicle(const Vehicle *v)
3481{
3482 Window *w = GetMainWindow();
3483 if (w->viewport->follow_vehicle == v->index) {
3484 ScrollMainWindowTo(v->x_pos, v->y_pos, v->z_pos, true); // lock the main view on the vehicle's last position
3485 w->viewport->CancelFollow(*w);
3486 }
3487}
3488
3489
3495 void CcBuildPrimaryVehicle(Commands, const CommandCost &result, VehicleID new_veh_id, uint, uint16_t, CargoArray)
3496{
3497 if (result.Failed()) return;
3498
3499 const Vehicle *v = Vehicle::Get(new_veh_id);
3500 ShowVehicleViewWindow(v);
3501}
3502
3508 int GetSingleVehicleWidth(const Vehicle *v, EngineImageType image_type)
3509{
3510 switch (v->type) {
3511 case VEH_TRAIN:
3512 return Train::From(v)->GetDisplayImageWidth();
3513
3514 case VEH_ROAD:
3515 return RoadVehicle::From(v)->GetDisplayImageWidth();
3516
3517 default:
3518 bool rtl = _current_text_dir == TD_RTL;
3519 VehicleSpriteSeq seq;
3520 v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq);
3521 Rect rec;
3522 seq.GetBounds(&rec);
3523 return UnScaleGUI(rec.Width());
3524 }
3525}
3526
3532 int GetVehicleWidth(const Vehicle *v, EngineImageType image_type)
3533{
3534 if (v->type == VEH_TRAIN || v->type == VEH_ROAD) {
3535 int vehicle_width = 0;
3536 for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
3537 vehicle_width += GetSingleVehicleWidth(u, image_type);
3538 }
3539 return vehicle_width;
3540 } else {
3541 return GetSingleVehicleWidth(v, image_type);
3542 }
3543}
3544
3550 void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type)
3551{
3552 bool rtl = _current_text_dir == TD_RTL;
3553
3554 _cursor.sprites.clear();
3555 int total_width = 0;
3556 int y_offset = 0;
3557 bool rotor_seq = false; // Whether to draw the rotor of the vehicle in this step.
3558 bool is_ground_vehicle = v->IsGroundVehicle();
3559
3560 while (v != nullptr) {
3561 if (total_width >= ScaleSpriteTrad(2 * (int)VEHICLEINFO_FULL_VEHICLE_WIDTH)) break;
3562
3563 PaletteID pal = v->vehstatus.Test(VehState::Crashed) ? PALETTE_CRASH : GetVehiclePalette(v);
3564 VehicleSpriteSeq seq;
3565
3566 if (rotor_seq) {
3567 GetCustomRotorSprite(Aircraft::From(v), image_type, &seq);
3568 if (!seq.IsValid()) seq.Set(SPR_ROTOR_STOPPED);
3569 y_offset = -ScaleSpriteTrad(5);
3570 } else {
3571 v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq);
3572 }
3573
3574 int x_offs = 0;
3575 if (v->type == VEH_TRAIN) x_offs = Train::From(v)->GetCursorImageOffset();
3576
3577 for (uint i = 0; i < seq.count; ++i) {
3578 PaletteID pal2 = v->vehstatus.Test(VehState::Crashed) || !seq.seq[i].pal ? pal : seq.seq[i].pal;
3579 _cursor.sprites.emplace_back(seq.seq[i].sprite, pal2, rtl ? (-total_width + x_offs) : (total_width + x_offs), y_offset);
3580 }
3581
3582 if (v->type == VEH_AIRCRAFT && v->subtype == AIR_HELICOPTER && !rotor_seq) {
3583 /* Draw rotor part in the next step. */
3584 rotor_seq = true;
3585 } else {
3586 total_width += GetSingleVehicleWidth(v, image_type);
3587 v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : nullptr;
3588 }
3589 }
3590
3591 if (is_ground_vehicle) {
3592 /* Center trains and road vehicles on the front vehicle */
3593 int offs = (ScaleSpriteTrad(VEHICLEINFO_FULL_VEHICLE_WIDTH) - total_width) / 2;
3594 if (rtl) offs = -offs;
3595 for (auto &cs : _cursor.sprites) {
3596 cs.pos.x += offs;
3597 }
3598 }
3599
3600 UpdateCursorSize();
3601}
aircraft.h
Base for aircraft.
VAF_DEST_TOO_FAR
@ VAF_DEST_TOO_FAR
Next destination is too far away.
Definition aircraft.h:37
AIR_HELICOPTER
@ AIR_HELICOPTER
an helicopter
Definition aircraft.h:29
DrawAircraftImage
void DrawAircraftImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type)
Draws an image of an aircraft.
Definition aircraft_gui.cpp:70
GetUnionOfArticulatedRefitMasks
CargoTypes GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type)
Ors the refit_masks of all articulated parts.
Definition articulated_vehicles.cpp:248
articulated_vehicles.h
Functions related to articulated vehicles.
ShowReplaceGroupVehicleWindow
void ShowReplaceGroupVehicleWindow(GroupID id_g, VehicleType vehicletype)
Show the autoreplace configuration window for a particular group.
Definition autoreplace_gui.cpp:882
autoreplace_gui.h
Functions related to the autoreplace GUIs.
VehicleFlag::PathfinderLost
@ PathfinderLost
Vehicle's pathfinder is lost.
GB
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
Definition bitmath_func.hpp:32
SetBit
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
Definition bitmath_func.hpp:121
CountBits
constexpr uint CountBits(T value)
Counts the number of set bits in a variable.
Definition bitmath_func.hpp:238
HasBit
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
Definition bitmath_func.hpp:103
HasAtMostOneBit
constexpr bool HasAtMostOneBit(T value)
Test whether value has at most 1 bit set.
Definition bitmath_func.hpp:266
CargoType
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:21
IsValidCargoType
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:104
GetLargestCargoIconSize
Dimension GetLargestCargoIconSize()
Get dimensions of largest cargo icon.
Definition cargotype.cpp:163
_sorted_cargo_specs
std::vector< const CargoSpec * > _sorted_cargo_specs
Cargo specifications sorted alphabetically by name.
Definition cargotype.cpp:190
_cargo_mask
CargoTypes _cargo_mask
Bitmask of cargo types available.
Definition cargotype.cpp:31
CargoClass::Passengers
@ Passengers
Passengers.
IsCargoInClass
bool IsCargoInClass(CargoType cargo, CargoClasses cc)
Does cargo c have cargo class cc?
Definition cargotype.h:236
BaseBitSet::Test
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Definition base_bitset_type.hpp:141
BaseBitSet::Set
constexpr Timpl & Set()
Set all bits.
Definition base_bitset_type.hpp:40
CommandCost
Common return value for all commands.
Definition command_type.h:24
CommandCost::Failed
bool Failed() const
Did this command fail?
Definition command_type.h:177
EconomyTime::DAYS_IN_ECONOMY_MONTH
static constexpr int DAYS_IN_ECONOMY_MONTH
Days in an economy month, when in wallclock timekeeping mode.
Definition timer_game_economy.h:53
Engine
Definition engine_base.h:38
Engine::GetAircraftTypeText
StringID GetAircraftTypeText() const
Get the name of the aircraft type for display purposes.
Definition engine.cpp:466
Engine::CanCarryCargo
bool CanCarryCargo() const
Determines whether an engine can carry something.
Definition engine.cpp:167
EnumBitSet< VehicleCallbackMask, uint16_t >
GUIList::Filter
bool Filter(FilterFunction *decide, F filter_data)
Filter the list.
Definition sortlist_type.h:342
GUIList::RebuildDone
void RebuildDone()
Notify the sortlist that the rebuild is done.
Definition sortlist_type.h:405
GUIList::SetListing
void SetListing(Listing l)
Import sort conditions.
Definition sortlist_type.h:148
GUIList::SetFilterState
void SetFilterState(bool state)
Enable or disable the filter.
Definition sortlist_type.h:326
GUIList::IsDescSortOrder
bool IsDescSortOrder() const
Check if the sort order is descending.
Definition sortlist_type.h:242
GUIList::ToggleSortOrder
void ToggleSortOrder()
Toggle the sort order Since that is the worst condition for the sort function reverse the list here.
Definition sortlist_type.h:252
GUIList< GUIVehicleGroup, std::nullptr_t, CargoType >::FilterFunction
bool(const GUIVehicleGroup *, CargoType) FilterFunction
Signature of filter function.
Definition sortlist_type.h:46
GUIList::SetFilterFuncs
void SetFilterFuncs(std::span< FilterFunction *const > n_funcs)
Hand the filter function pointers to the GUIList.
Definition sortlist_type.h:365
GUIList::NeedRebuild
bool NeedRebuild() const
Check if a rebuild is needed.
Definition sortlist_type.h:387
GUIList::SetFilterType
void SetFilterType(uint8_t n_type)
Set the filtertype of the list.
Definition sortlist_type.h:173
GUIList::ForceRebuild
void ForceRebuild()
Force that a rebuild is needed.
Definition sortlist_type.h:395
GUIList::Sort
bool Sort(Comp compare)
Sort the list.
Definition sortlist_type.h:266
GUIList::ForceResort
void ForceResort()
Force a resort next Sort call Reset the resort timer if used too.
Definition sortlist_type.h:232
GUIList::SortType
uint8_t SortType() const
Get the sorttype of the list.
Definition sortlist_type.h:110
GUIList::GetListing
Listing GetListing() const
Export current sort conditions.
Definition sortlist_type.h:134
GUIList::SetSortFuncs
void SetSortFuncs(std::span< SortFunction *const > n_funcs)
Hand the sort function pointers to the GUIList.
Definition sortlist_type.h:293
GUIList::NeedResort
bool NeedResort()
Check if a resort is needed next loop If used the resort timer will decrease every call till 0.
Definition sortlist_type.h:218
GUIList::SetSortType
void SetSortType(uint8_t n_type)
Set the sorttype of the list.
Definition sortlist_type.h:120
NWidgetBase
Baseclass for nested widgets.
Definition widget_type.h:137
NWidgetBase::SetDirty
virtual void SetDirty(const Window *w) const
Mark the widget as 'dirty' (in need of repaint).
Definition widget.cpp:949
NWidgetBase::current_x
uint current_x
Current horizontal size (after resizing).
Definition widget_type.h:238
NWidgetBase::pos_x
int pos_x
Horizontal position of top-left corner of the widget in the window.
Definition widget_type.h:243
NWidgetBase::current_y
uint current_y
Current vertical size (after resizing).
Definition widget_type.h:239
NWidgetCore
Base class for a 'real' widget.
Definition widget_type.h:371
NWidgetCore::SetStringTip
void SetStringTip(StringID string, StringID tool_tip)
Set string and tool tip of the nested widget.
Definition widget.cpp:1192
NWidgetStacked
Stacked widgets, widgets all occupying the same space in the window.
Definition widget_type.h:524
NWidgetStacked::shown_plane
int shown_plane
Plane being displayed (for NWID_SELECTION only).
Definition widget_type.h:537
NWidgetStacked::SetDisplayedPlane
bool SetDisplayedPlane(int plane)
Select which plane to show (for NWID_SELECTION only).
Definition widget.cpp:1450
NWidgetViewport
Nested widget to display a viewport in a window.
Definition widget_type.h:697
NWidgetViewport::UpdateViewportCoordinates
void UpdateViewportCoordinates(Window *w)
Update the position and size of the viewport (after eg a resize).
Definition widget.cpp:2430
OverflowSafeInt< int64_t >
Scrollbar
Scrollbar data structure.
Definition widget_type.h:711
Scrollbar::SetCount
void SetCount(size_t num)
Sets the number of elements in the list.
Definition widget_type.h:795
Scrollbar::GetScrolledItemFromWidget
auto GetScrolledItemFromWidget(Tcontainer &container, int clickpos, const Window *const w, WidgetID widget, int padding=0, int line_height=-1) const
Return an iterator pointing to the element of a scrolled widget that a user clicked in.
Definition widget_type.h:894
Scrollbar::GetScrolledRowFromWidget
size_type GetScrolledRowFromWidget(int clickpos, const Window *const w, WidgetID widget, int padding=0, int line_height=-1) const
Compute the row of a scrolled widget that a user clicked in.
Definition widget.cpp:2453
Scrollbar::SetCapacityFromWidget
void SetCapacityFromWidget(Window *w, WidgetID widget, int padding=0)
Set capacity of visible elements from the size and resize properties of a widget.
Definition widget.cpp:2527
Scrollbar::ScrollTowards
void ScrollTowards(size_type position)
Scroll towards the given position; if the item is visible nothing happens, otherwise it will be shown...
Definition widget_type.h:856
Scrollbar::GetVisibleRangeIterators
auto GetVisibleRangeIterators(Tcontainer &container) const
Get a pair of iterators for the range of visible elements in a container.
Definition widget_type.h:875
Scrollbar::GetPosition
size_type GetPosition() const
Gets the position of the first visible element in the list.
Definition widget_type.h:755
Ticks::DAY_TICKS
static constexpr TimerGameTick::Ticks DAY_TICKS
1 day is 74 ticks; TimerGameCalendar::date_fract used to be uint16_t and incremented by 885.
Definition timer_game_tick.h:75
TimerGameConst< struct Economy >::MAX_DATE
static constexpr TimerGame< struct Economy >::Date MAX_DATE
The date of the last day of the max year.
Definition timer_game_common.h:187
TimerGameConst< struct Calendar >::DAYS_IN_YEAR
static constexpr int DAYS_IN_YEAR
days per year
Definition timer_game_common.h:149
TimerGameConst< struct Economy >::MAX_YEAR
static constexpr TimerGame< struct Economy >::Year MAX_YEAR
MAX_YEAR, nicely rounded value of the number of years that can be encoded in a single 32 bits date,...
Definition timer_game_common.h:173
TimerGameConst< struct Calendar >::DAYS_IN_LEAP_YEAR
static constexpr int DAYS_IN_LEAP_YEAR
sometimes, you need one day more...
Definition timer_game_common.h:150
TimerGameEconomy::date
static Date date
Current date in days (day counter).
Definition timer_game_economy.h:38
TimerGameEconomy::UsingWallclockUnits
static bool UsingWallclockUnits(bool newgame=false)
Check if we are using wallclock units.
Definition timer_game_economy.cpp:98
TimerGame< struct Calendar >::DateToYear
static constexpr Year DateToYear(Date date)
Calculate the year of a given date.
Definition timer_game_common.h:77
TimerGame< struct Economy >::DateAtStartOfYear
static constexpr Date DateAtStartOfYear(Year year)
Calculate the date of the first day of a given year.
Definition timer_game_common.h:88
WidgetDimensions::framerect
RectPadding framerect
Standard padding inside many panels.
Definition window_gui.h:40
WidgetDimensions::scaled
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:30
WidgetDimensions::vsep_normal
int vsep_normal
Normal vertical spacing.
Definition window_gui.h:58
WidgetDimensions::hsep_wide
int hsep_wide
Wide horizontal spacing.
Definition window_gui.h:62
WidgetDimensions::unscaled
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition window_gui.h:93
WidgetDimensions::matrix
RectPadding matrix
Padding of WWT_MATRIX items.
Definition window_gui.h:42
WidgetDimensions::hsep_normal
int hsep_normal
Normal horizontal spacing.
Definition window_gui.h:61
WidgetDimensions::bevel
RectPadding bevel
Bevel thickness, affected by "scaled bevels" game option.
Definition window_gui.h:38
command_func.h
Functions related to commands.
DoCommandFlag::QueryCost
@ QueryCost
query cost only, don't build.
Commands
Commands
List of commands.
Definition command_type.h:196
company_base.h
Definition of stuff that is very close to a company, like the company struct itself.
_local_company
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition company_cmd.cpp:55
_current_company
CompanyID _current_company
Company currently doing an action.
Definition company_cmd.cpp:56
company_func.h
Functions related to companies.
OWNER_NONE
static constexpr Owner OWNER_NONE
The tile has no ownership.
Definition company_type.h:26
container_func.hpp
Some simple functions to help with accessing containers.
include
bool include(Container &container, typename Container::const_reference &item)
Helper function to append an item to a container if it is not already contained.
Definition container_func.hpp:24
debug.h
Functions related to debugging.
Debug
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Definition debug.h:37
depot_cmd.h
Command definitions related to depots.
CcCloneVehicle
void CcCloneVehicle(Commands cmd, const CommandCost &result, VehicleID veh_id)
This is the Callback method after the cloning attempt of a vehicle.
Definition depot_gui.cpp:124
depot_map.h
Map related accessors for depots.
GetDepotDestinationIndex
DestinationID GetDepotDestinationIndex(Tile t)
Get the destination index of a 'depot'.
Definition depot_map.h:66
DIR_W
@ DIR_W
West.
Definition direction_type.h:32
DIR_E
@ DIR_E
East.
Definition direction_type.h:28
ShowDropDownMenu
void ShowDropDownMenu(Window *w, std::span< const StringID > strings, int selected, WidgetID button, uint32_t disabled_mask, uint32_t hidden_mask, uint width)
Show a dropdown menu window near a widget of the parent window.
Definition dropdown.cpp:458
GetDropDownListDimension
Dimension GetDropDownListDimension(const DropDownList &list)
Determine width and height required to fully display a DropDownList.
Definition dropdown.cpp:381
ShowDropDownList
void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width, DropDownOptions options)
Show a drop down list.
Definition dropdown.cpp:418
dropdown_func.h
Functions related to the drop down widget.
dropdown_type.h
Types related to the drop down widget.
DropDownList
std::vector< std::unique_ptr< const DropDownListItem > > DropDownList
A drop down list is a collection of drop down list items.
Definition dropdown_type.h:56
IsEngineRefittable
bool IsEngineRefittable(EngineID engine)
Check if an engine is refittable.
Definition engine.cpp:1287
engine_func.h
Functions related to engines.
EngineMiscFlag::AutoRefit
@ AutoRefit
Automatic refitting is allowed.
VehicleAccelerationModel::Maglev
@ Maglev
Maglev acceleration model.
GetCharacterHeight
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:87
maxdim
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Definition geometry_func.cpp:22
geometry_func.hpp
Geometry functions.
CentreBounds
int CentreBounds(int min, int max, int size)
Determine where to position a centred object.
Definition geometry_type.hpp:26
GetSpriteSize
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition gfx.cpp:968
UpdateCursorSize
void UpdateCursorSize()
Update cursor dimension.
Definition gfx.cpp:1618
_shift_pressed
bool _shift_pressed
Is Shift pressed?
Definition gfx.cpp:39
GetStringBoundingBox
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:897
GetStringListBoundingBox
Dimension GetStringListBoundingBox(std::span< const StringID > list, FontSize fontsize)
Get maximum dimension of a list of strings.
Definition gfx.cpp:935
DrawString
int DrawString(int left, int right, int top, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition gfx.cpp:668
_ctrl_pressed
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:38
GetStringListWidth
uint GetStringListWidth(std::span< const StringID > list, FontSize fontsize)
Get maximum width of a list of strings.
Definition gfx.cpp:920
DrawSprite
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition gfx.cpp:1034
DrawStringMultiLine
int DrawStringMultiLine(int left, int right, int top, int bottom, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly over multiple lines.
Definition gfx.cpp:785
GetScaledSpriteSize
Dimension GetScaledSpriteSize(SpriteID sprid)
Scale sprite size for GUI.
Definition widget.cpp:68
SpriteID
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
FS_SMALL
@ FS_SMALL
Index of the small font in the font tables.
Definition gfx_type.h:250
FS_NORMAL
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:249
SA_LEFT
@ SA_LEFT
Left align the text.
Definition gfx_type.h:388
SA_HOR_CENTER
@ SA_HOR_CENTER
Horizontally center the text.
Definition gfx_type.h:389
SA_CENTER
@ SA_CENTER
Center both horizontally and vertically.
Definition gfx_type.h:398
PaletteID
uint32_t PaletteID
The number of the palette.
Definition gfx_type.h:18
TextColour
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition gfx_type.h:307
TC_FORCED
@ TC_FORCED
Ignore colour changes from strings.
Definition gfx_type.h:332
SetMatrixDataTip
constexpr NWidgetPart SetMatrixDataTip(uint32_t cols, uint32_t rows, StringID tip={})
Widget part function for setting the data and tooltip of WWT_MATRIX widgets.
Definition widget_type.h:1311
SetFill
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
Definition widget_type.h:1222
SetSpriteTip
constexpr NWidgetPart SetSpriteTip(SpriteID sprite, StringID tip={})
Widget part function for setting the sprite and tooltip.
Definition widget_type.h:1254
SetScrollbar
constexpr NWidgetPart SetScrollbar(WidgetID index)
Attach a scrollbar to a widget.
Definition widget_type.h:1402
SetPadding
constexpr NWidgetPart SetPadding(uint8_t top, uint8_t right, uint8_t bottom, uint8_t left)
Widget part function for setting additional space around a widget.
Definition widget_type.h:1335
SetStringTip
constexpr NWidgetPart SetStringTip(StringID string, StringID tip={})
Widget part function for setting the string and tooltip.
Definition widget_type.h:1243
SetAspect
constexpr NWidgetPart SetAspect(float ratio, AspectFlags flags=AspectFlag::ResizeX)
Widget part function for setting the aspect ratio.
Definition widget_type.h:1413
SetMinimalSize
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
Definition widget_type.h:1159
SetToolTip
constexpr NWidgetPart SetToolTip(StringID tip)
Widget part function for setting tooltip and clearing the widget data.
Definition widget_type.h:1321
EndContainer
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
Definition widget_type.h:1232
SetArrowWidgetTypeTip
constexpr NWidgetPart SetArrowWidgetTypeTip(ArrowWidgetValues widget_type, StringID tip={})
Widget part function for setting the arrow widget type and tooltip.
Definition widget_type.h:1277
NWidget
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=INVALID_WIDGET)
Widget part function for starting a new 'real' widget.
Definition widget_type.h:1427
SetMinimalTextLines
constexpr NWidgetPart SetMinimalTextLines(uint8_t lines, uint8_t spacing, FontSize size=FS_NORMAL)
Widget part function for setting the minimal text lines.
Definition widget_type.h:1190
SetResize
constexpr NWidgetPart SetResize(int16_t dx, int16_t dy)
Widget part function for setting the resize step.
Definition widget_type.h:1148
group_cmd.h
Command definitions related to engine groups.
CcAddVehicleNewGroup
void CcAddVehicleNewGroup(Commands cmd, const CommandCost &result, GroupID new_group, GroupID, VehicleID veh_id, bool, const VehicleListIdentifier &)
Open rename window after adding a vehicle to a new group via drag and drop.
Definition group_gui.cpp:1295
Window::SetDirty
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition window.cpp:968
ShowCompanyGroup
void ShowCompanyGroup(CompanyID company, VehicleType vehicle_type, GroupID group)
Show the group window for the given company and vehicle type.
Definition group_gui.cpp:1240
ShowCompanyGroupForVehicle
void ShowCompanyGroupForVehicle(const Vehicle *v)
Show the group window for the given vehicle.
Definition group_gui.cpp:1249
group_gui.h
Functions/definitions that have something to do with groups.
DEFAULT_GROUP
static constexpr GroupID DEFAULT_GROUP
Ungrouped vehicles are in this group.
Definition group_type.h:18
ALL_GROUP
static constexpr GroupID ALL_GROUP
All vehicles are in this group.
Definition group_type.h:17
NEW_GROUP
static constexpr GroupID NEW_GROUP
Sentinel for a to-be-created group.
Definition group_type.h:16
gui.h
GUI functions that shouldn't be here.
ShowExtraViewportWindow
void ShowExtraViewportWindow(TileIndex tile=INVALID_TILE)
Show a new Extra Viewport window.
Definition viewport_gui.cpp:159
hotkeys.h
Hotkey related functions.
RemapCoords
Point RemapCoords(int x, int y, int z)
Map 3D world or tile coordinate to equivalent 2D coordinate as used in the viewports and smallmap.
Definition landscape.h:81
DoZoomInOutWindow
bool DoZoomInOutWindow(ZoomStateChange how, Window *w)
Zooms a viewport in a window in or out.
Definition main_gui.cpp:93
TileVirtXY
static TileIndex TileVirtXY(uint x, uint y)
Get a tile from the virtual XY-coordinate.
Definition map_func.h:416
ToPercent16
constexpr uint ToPercent16(uint i)
Converts a "fract" value 0..65535 to "percent" value 0..100.
Definition math_func.hpp:296
Clamp
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
GuiShowTooltips
void GuiShowTooltips(Window *parent, EncodedString &&text, TooltipCloseCondition close_tooltip)
Shows a tooltip.
Definition misc_gui.cpp:693
ShowQueryString
void ShowQueryString(std::string_view str, StringID caption, uint maxsize, Window *parent, CharSetFilter afilter, QueryStringFlags flags)
Show a query popup window with a textbox in it.
Definition misc_gui.cpp:1064
CargoFilterCriteria::CF_FREIGHT
static constexpr CargoType CF_FREIGHT
Show only vehicles which carry any freight (non-passenger) cargo.
Definition cargo_type.h:96
CargoFilterCriteria::CF_NONE
static constexpr CargoType CF_NONE
Show only items which do not carry cargo (e.g. train engines)
Definition cargo_type.h:94
CargoFilterCriteria::CF_ANY
static constexpr CargoType CF_ANY
Show all items independent of carried cargo (i.e. no filtering)
Definition cargo_type.h:93
VehicleCallbackMask::CargoSuffix
@ CargoSuffix
Show suffix after cargo name.
CBID_VEHICLE_CARGO_SUFFIX
@ CBID_VEHICLE_CARGO_SUFFIX
Determine the cargo "suffixes" for each refit possibility of a cargo.
Definition newgrf_callbacks.h:62
CALLBACK_FAILED
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
Definition newgrf_callbacks.h:439
ErrorUnknownCallbackResult
void ErrorUnknownCallbackResult(uint32_t grfid, uint16_t cbid, uint16_t cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
Definition newgrf_commons.cpp:517
newgrf_debug.h
Functions/types related to NewGRF debugging.
GetGrfSpecFeature
GrfSpecFeature GetGrfSpecFeature(TileIndex tile)
Get the GrfSpecFeature associated with the tile.
Definition newgrf_debug_gui.cpp:760
GetVehicleCallback
uint16_t GetVehicleCallback(CallbackID callback, uint32_t param1, uint32_t param2, EngineID engine, const Vehicle *v, std::span< int32_t > regs100)
Evaluate a newgrf callback for vehicles.
Definition newgrf_engine.cpp:1198
GetGRFStringID
StringID GetGRFStringID(uint32_t grfid, GRFStringID stringid)
Returns the index for this stringid associated with its grfID.
Definition newgrf_text.cpp:580
newgrf_text.h
Header of Action 04 "universal holder" structure and functions.
GRFSTR_MISC_GRF_TEXT
static constexpr GRFStringID GRFSTR_MISC_GRF_TEXT
Miscellaneous GRF text range.
Definition newgrf_text_type.h:18
GetServiceIntervalClamped
uint16_t GetServiceIntervalClamped(int interval, bool ispercent)
Clamp the service interval to the correct min/max.
Definition order_cmd.cpp:1865
order_cmd.h
Command definitions related to orders.
VehicleOrderID
uint8_t VehicleOrderID
The index of an order within its current vehicle (not pool related)
Definition order_type.h:18
OrderDepotActionFlag::Halt
@ Halt
Service the vehicle and then halt it.
OrderDepotActionFlag::Unbunch
@ Unbunch
Service the vehicle and then unbunch it.
INVALID_VEH_ORDER_ID
static const VehicleOrderID INVALID_VEH_ORDER_ID
Invalid vehicle order index (sentinel)
Definition order_type.h:39
GetColourGradient
PixelColour GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
Definition palette.cpp:388
roadveh.h
Road vehicle states.
roadveh_cmd.h
Command definitions related to road vehicles.
DrawRoadVehImage
void DrawRoadVehImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type, int skip)
Draws an image of a road vehicle chain.
Definition roadveh_gui.cpp:112
safeguards.h
A number of safeguards to prevent using unsafe methods.
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
SWS_OFF
@ SWS_OFF
Scroll wheel has no effect.
Definition settings_type.h:159
DrawShipImage
void DrawShipImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type)
Draws an image of a ship.
Definition ship_gui.cpp:29
ScrollMainWindowTo
bool ScrollMainWindowTo(int x, int y, int z, bool instant)
Scrolls the main window to given coordinates.
Definition smallmap_gui.cpp:2078
PALETTE_ALL_BLACK
static const PaletteID PALETTE_ALL_BLACK
Exchange any colour by black, needed for painting fictive tiles outside map.
Definition sprites.h:1625
PALETTE_CRASH
static const PaletteID PALETTE_CRASH
Recolour sprite greying of crashed vehicles.
Definition sprites.h:1619
SPR_CURSOR_MOUSE
static const CursorID SPR_CURSOR_MOUSE
Cursor sprite numbers.
Definition sprites.h:1404
SPR_CLONE_TRAIN
static const SpriteID SPR_CLONE_TRAIN
Clone vehicles stuff.
Definition sprites.h:100
station_base.h
Base classes/functions for stations.
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
StrNaturalCompare
int StrNaturalCompare(std::string_view s1, std::string_view s2, bool ignore_garbage_at_front)
Compares two strings using case insensitive natural sort.
Definition string.cpp:427
string_func.h
Functions related to low-level strings.
CS_ALPHANUMERAL
@ CS_ALPHANUMERAL
Both numeric and alphabetic and spaces and stuff.
Definition string_type.h:25
GetParamMaxValue
uint64_t GetParamMaxValue(uint64_t max_value, uint min_count, FontSize size)
Get some number that is suitable for string size computations.
Definition strings.cpp:236
GetStringWithArgs
void GetStringWithArgs(StringBuilder &builder, StringID string, StringParameters &args, uint case_index, bool game_script)
Get a parsed string with most special stringcodes replaced by the string parameters.
Definition strings.cpp:336
GetEncodedString
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
GetString
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:424
_current_text_dir
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:56
GetParamMaxDigits
uint64_t GetParamMaxDigits(uint count, FontSize size)
Get some number that is suitable for string size computations.
Definition strings.cpp:218
strings_func.h
Functions related to OTTD's strings.
PrepareArgsForNextRun
static void PrepareArgsForNextRun(std::span< StringParameter > args)
Prepare the string parameters for the next formatting run, resetting the type information.
Definition strings_func.h:63
MakeParameters
auto MakeParameters(Args &&... args)
Helper to create the StringParameters with its own buffer with the given parameter values.
Definition strings_func.h:107
PackVelocity
int64_t PackVelocity(uint speed, VehicleType type)
Pack velocity and vehicle type for use with SCC_VELOCITY string parameter.
Definition strings_func.h:83
StringID
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition strings_type.h:19
INVALID_STRING_ID
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Definition strings_type.h:20
TD_RTL
@ TD_RTL
Text is written right-to-left by default.
Definition strings_type.h:27
Aircraft
Aircraft, helicopters, rotors and their shadows belong to this class.
Definition aircraft.h:72
BaseConsist::name
std::string name
Name of vehicle.
Definition base_consist.h:34
BaseConsist::cur_real_order_index
VehicleOrderID cur_real_order_index
The index to the current real (non-implicit) order.
Definition base_consist.h:47
BaseConsist::vehicle_flags
VehicleFlags vehicle_flags
Used for gradual loading and other miscellaneous things (.
Definition base_consist.h:50
BaseConsist::lateness_counter
TimerGameTick::Ticks lateness_counter
How many ticks late (or early if negative) this vehicle is.
Definition base_consist.h:38
BaseVehicleListWindow
Definition vehicle_gui_base.h:67
BaseVehicleListWindow::vli
VehicleListIdentifier vli
Identifier of the vehicle list we want to currently show.
Definition vehicle_gui_base.h:82
BaseVehicleListWindow::DrawVehicleListItems
void DrawVehicleListItems(VehicleID selected_vehicle, int line_height, const Rect &r) const
Draw all the vehicle list items.
Definition vehicle_gui.cpp:1757
BaseVehicleListWindow::vehicle_sel
VehicleID vehicle_sel
Selected vehicle.
Definition vehicle_gui_base.h:83
BaseVehicleListWindow::sorting
Listing * sorting
Pointer to the vehicle type related sorting.
Definition vehicle_gui_base.h:79
BaseVehicleListWindow::SetCargoFilter
void SetCargoFilter(uint8_t index)
Set cargo filter for the vehicle group list.
Definition vehicle_gui.cpp:417
BaseVehicleListWindow::grouping
GroupBy grouping
How we want to group the list.
Definition vehicle_gui_base.h:76
BaseVehicleListWindow::GetActionDropdownSize
Dimension GetActionDropdownSize(bool show_autoreplace, bool show_group, bool show_create)
Compute the size for the Action dropdown.
Definition vehicle_gui.cpp:459
BaseVehicleListWindow::order_arrow_width
uint order_arrow_width
Width of the arrow in the small order list.
Definition vehicle_gui_base.h:85
BaseVehicleListWindow::unitnumber_digits
uint8_t unitnumber_digits
The number of digits of the highest unit number.
Definition vehicle_gui_base.h:80
BaseVehicleListWindow::BuildActionDropdownList
DropDownList BuildActionDropdownList(bool show_autoreplace, bool show_group, bool show_create)
Display the Action dropdown window.
Definition vehicle_gui.cpp:526
BaseVehicleListWindow::vehicles
VehicleList vehicles
List of vehicles. This is the buffer for vehgroups to point into; if this is structurally modified,...
Definition vehicle_gui_base.h:77
BaseVehicleListWindow::vehgroups
GUIVehicleGroupList vehgroups
List of (groups of) vehicles. This stores iterators of vehicles, and should be rebuilt if vehicles is...
Definition vehicle_gui_base.h:78
BaseVehicleListWindow::SetCargoFilterArray
void SetCargoFilterArray()
Populate the filter list and set the cargo filter criteria.
Definition vehicle_gui.cpp:431
BaseVehicleListWindow::BuildCargoDropDownList
DropDownList BuildCargoDropDownList(bool full) const
Build drop down list for cargo filter selection.
Definition vehicle_gui.cpp:498
BaseVehicleListWindow::OnInit
void OnInit() override
Notification that the nested widget tree gets initialized.
Definition vehicle_gui.cpp:477
BaseVehicleListWindow::cargo_filter_criteria
CargoType cargo_filter_criteria
Selected cargo filter index.
Definition vehicle_gui_base.h:84
BaseVehicleListWindow::FilterVehicleList
void FilterVehicleList()
Filter the engine list against the currently selected cargo filter.
Definition vehicle_gui.cpp:441
BaseVehicle::type
VehicleType type
Type of vehicle.
Definition vehicle_type.h:51
CargoArray
Class for storing amounts of cargo.
Definition cargo_type.h:111
CargoSpec
Specification of a cargo type.
Definition cargotype.h:74
CargoSpec::Get
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo type.
Definition cargotype.h:137
CargoSpec::GetCargoIcon
SpriteID GetCargoIcon() const
Get sprite for showing cargo of this type.
Definition cargotype.cpp:176
CargoSpec::name
StringID name
Name of this type of cargo.
Definition cargotype.h:91
CargoTypeComparator
Comparator to sort CargoType by according to desired order.
Definition cargotype.h:244
ClientSettings::gui
GUISettings gui
settings related to the GUI
Definition settings_type.h:650
CommandHelper
Definition command_func.h:84
Coord2D< int >
Coord2D::y
T y
Y coordinate.
Definition geometry_type.hpp:35
Coord2D::x
T x
X coordinate.
Definition geometry_type.hpp:34
CursorVars::sprites
std::vector< CursorSprite > sprites
Sprites comprising cursor.
Definition gfx_type.h:136
Dimension
Dimensions (a width and height) of a rectangle in 2D.
Definition geometry_type.hpp:56
EngineInfo::misc_flags
EngineMiscFlags misc_flags
Miscellaneous flags.
Definition engine_type.h:209
EngineInfo::callback_mask
VehicleCallbackMasks callback_mask
Bitmask of vehicle callbacks that have to be called.
Definition engine_type.h:210
GUISettings::show_cargo_in_vehicle_lists
bool show_cargo_in_vehicle_lists
Show the cargoes the vehicles can carry in the list windows.
Definition settings_type.h:234
GUISettings::scrollwheel_scrolling
uint8_t scrollwheel_scrolling
scrolling using the scroll wheel?
Definition settings_type.h:203
GUISettings::advanced_vehicle_list
uint8_t advanced_vehicle_list
use the "advanced" vehicle list
Definition settings_type.h:184
GUIVehicleGroup
Definition vehicle_gui_base.h:24
GUIVehicleGroup::vehicles_end
VehicleList::const_iterator vehicles_end
Pointer to past-the-end element of this vehicle group.
Definition vehicle_gui_base.h:26
GUIVehicleGroup::vehicles_begin
VehicleList::const_iterator vehicles_begin
Pointer to beginning element of this vehicle group.
Definition vehicle_gui_base.h:25
GameSettings::vehicle
VehicleSettings vehicle
options for vehicles
Definition settings_type.h:641
GroundVehicleCache
Cached, frequently calculated values.
Definition ground_vehicle.hpp:30
GroundVehicleCache::cached_weight
uint32_t cached_weight
Total weight of the consist (valid only for the first engine).
Definition ground_vehicle.hpp:32
GroundVehicleCache::cached_power
uint32_t cached_power
Total power of the consist (valid only for the first engine).
Definition ground_vehicle.hpp:39
GroundVehicleCache::cached_total_length
uint16_t cached_total_length
Length of the whole vehicle (valid only for the first engine).
Definition ground_vehicle.hpp:43
GroundVehicleCache::cached_max_te
uint32_t cached_max_te
Maximum tractive effort of consist (valid only for the first engine).
Definition ground_vehicle.hpp:34
HotkeyList
List of hotkeys for a window.
Definition hotkeys.h:37
Hotkey
All data for a single hotkey.
Definition hotkeys.h:21
OrderList
Shared order list linking together the linked list of orders and the list of vehicles sharing this or...
Definition order_base.h:274
OrderList::GetNext
VehicleOrderID GetNext(VehicleOrderID cur) const
Get the order after the given one or the first one, if the given one is the last one.
Definition order_base.h:362
Order
Definition order_base.h:33
Order::GetLocation
TileIndex GetLocation(const Vehicle *v, bool airport=false) const
Returns a tile somewhat representing the order destination (not suitable for pathfinding).
Definition order_cmd.cpp:562
Order::GetDestination
DestinationID GetDestination() const
Gets the destination of this order.
Definition order_base.h:99
Order::IsType
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition order_base.h:66
Order::GetType
OrderType GetType() const
Get the type of order of this order.
Definition order_base.h:72
Order::GetDepotActionType
OrderDepotActionFlags GetDepotActionType() const
What are we going to do when in the depot.
Definition order_base.h:152
PixelColour
Colour for pixel/line drawing.
Definition gfx_type.h:405
PoolID< uint32_t, struct VehicleIDTag, 0xFF000, 0xFFFFF >
Pool::PoolItem<&_vehicle_pool >::Get
static Titem * Get(auto index)
Returns Titem with given index.
Definition pool_type.hpp:387
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition pool_type.hpp:286
Pool::PoolItem<&_company_pool >::IsValidID
static bool IsValidID(auto index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition pool_type.hpp:376
Pool::PoolItem<&_vehicle_pool >::GetIfValid
static Titem * GetIfValid(auto index)
Returns Titem with given index.
Definition pool_type.hpp:398
RectPadding::Horizontal
constexpr uint Horizontal() const
Get total horizontal padding of RectPadding.
Definition geometry_type.hpp:89
RectPadding::Vertical
constexpr uint Vertical() const
Get total vertical padding of RectPadding.
Definition geometry_type.hpp:95
Rect
Specification of a rectangle with absolute coordinates of all edges.
Definition geometry_type.hpp:101
Rect::WithWidth
Rect WithWidth(int width, bool end) const
Copy Rect and set its width.
Definition geometry_type.hpp:211
Rect::Width
int Width() const
Get width of Rect.
Definition geometry_type.hpp:111
Rect::Shrink
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
Definition geometry_type.hpp:124
Rect::WithHeight
Rect WithHeight(int height, bool end=false) const
Copy Rect and set its height.
Definition geometry_type.hpp:237
Rect::Indent
Rect Indent(int indent, bool end) const
Copy Rect and indent it from its position.
Definition geometry_type.hpp:224
Rect::WithX
Rect WithX(int new_left, int new_right) const
Create a new Rect, replacing the left and right coordiates.
Definition geometry_type.hpp:272
Rect::Translate
Rect Translate(int x, int y) const
Copy and translate Rect by x,y pixels.
Definition geometry_type.hpp:200
Rect::Expand
Rect Expand(int s) const
Copy and expand Rect by s pixels.
Definition geometry_type.hpp:179
RefitOption
Option to refit a vehicle chain.
Definition vehicle_gui.cpp:664
RefitOption::string
StringID string
GRF-local String to display for the cargo.
Definition vehicle_gui.cpp:667
RefitOption::cargo
CargoType cargo
Cargo to refit to.
Definition vehicle_gui.cpp:665
RefitOption::subtype
uint8_t subtype
Subcargo to use.
Definition vehicle_gui.cpp:666
RefitOption::operator==
bool operator==(const RefitOption &other) const
Equality operator for RefitOption.
Definition vehicle_gui.cpp:674
RefitWindow
Refit cargo window.
Definition vehicle_gui.cpp:745
RefitWindow::OnInit
void OnInit() override
Notification that the nested widget tree gets initialized.
Definition vehicle_gui.cpp:948
RefitWindow::information_width
uint information_width
Width required for correctly displaying all cargoes in the information panel.
Definition vehicle_gui.cpp:749
RefitWindow::SetSelection
void SetSelection(uint click_row)
Select a row.
Definition vehicle_gui.cpp:907
RefitWindow::BuildRefitList
void BuildRefitList()
Collects all (cargo, subcargo) refit options of a vehicle chain.
Definition vehicle_gui.cpp:764
RefitWindow::OnClick
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition vehicle_gui.cpp:1234
RefitWindow::sprite_left
int sprite_left
Left position of the vehicle sprite.
Definition vehicle_gui.cpp:753
RefitWindow::RefreshScrollbar
void RefreshScrollbar()
Refresh scrollbar after selection changed.
Definition vehicle_gui.cpp:883
RefitWindow::refit_list
RefitOptions refit_list
List of refit subtypes available for each sorted cargo.
Definition vehicle_gui.cpp:747
RefitWindow::OnMouseDrag
void OnMouseDrag(Point pt, WidgetID widget) override
An 'object' is being dragged at the provided position, highlight the target if possible.
Definition vehicle_gui.cpp:1276
RefitWindow::OnResize
void OnResize() override
Called after the window got resized.
Definition vehicle_gui.cpp:1302
RefitWindow::DrawWidget
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition vehicle_gui.cpp:1039
RefitWindow::selected_refit
const RefitOption * selected_refit
Selected refit option.
Definition vehicle_gui.cpp:746
RefitWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition vehicle_gui.cpp:1127
RefitWindow::vehicle_margin
uint vehicle_margin
Margin to use while selecting vehicles when the vehicle image is centered.
Definition vehicle_gui.cpp:755
RefitWindow::num_vehicles
uint8_t num_vehicles
Number of selected vehicles.
Definition vehicle_gui.cpp:758
RefitWindow::auto_refit
bool auto_refit
Select cargo for auto-refitting.
Definition vehicle_gui.cpp:759
RefitWindow::sprite_right
int sprite_right
Right position of the vehicle sprite.
Definition vehicle_gui.cpp:754
RefitWindow::order
VehicleOrderID order
If not INVALID_VEH_ORDER_ID, selection is part of a refit order (rather than execute directly).
Definition vehicle_gui.cpp:748
RefitWindow::selected_vehicle
VehicleID selected_vehicle
First vehicle in the current selection.
Definition vehicle_gui.cpp:757
RefitWindow::OnPaint
void OnPaint() override
The window must be repainted.
Definition vehicle_gui.cpp:954
RefitWindow::OnDragDrop
void OnDragDrop(Point pt, WidgetID widget) override
A dragged 'object' has been released.
Definition vehicle_gui.cpp:1289
RefitWindow::UpdateWidgetSize
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
Definition vehicle_gui.cpp:975
RefitWindow::hscroll
Scrollbar * hscroll
Only used for long vehicles.
Definition vehicle_gui.cpp:751
RefitWindow::vehicle_width
int vehicle_width
Width of the vehicle being drawn.
Definition vehicle_gui.cpp:752
RefitWindow::vscroll
Scrollbar * vscroll
The main scrollbar.
Definition vehicle_gui.cpp:750
RefitWindow::click_x
int click_x
Position of the first click while dragging.
Definition vehicle_gui.cpp:756
RefitWindow::GetWidgetString
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
Definition vehicle_gui.cpp:993
RefitWindow::GetCapacityString
std::string GetCapacityString(const RefitOption &option) const
Gets the StringID to use for displaying capacity.
Definition vehicle_gui.cpp:1006
ResizeInfo::step_height
uint step_height
Step-size of height resize changes.
Definition window_gui.h:213
SpecializedStation< Station, false >::IsExpected
static bool IsExpected(const BaseStation *st)
Helper for checking whether the given station is of this type.
Definition base_station_base.h:229
SpecializedVehicle::Next
T * Next() const
Get next vehicle in the chain.
Definition vehicle_base.h:1049
SpecializedVehicle::From
static T * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
Definition vehicle_base.h:1134
StrongType::Typedef
Templated helper to make a type-safe 'typedef' representing a single POD value.
Definition strong_typedef_type.hpp:130
TileHighlightData::GetCallbackWnd
Window * GetCallbackWnd()
Get the window that started the current highlighting.
Definition viewport.cpp:2665
TileHighlightData::place_mode
HighLightStyle place_mode
Method which is used to place the selection.
Definition tilehighlight_type.h:67
TileHighlightData::window_class
WindowClass window_class
The WindowClass of the window that is responsible for the selection mode.
Definition tilehighlight_type.h:68
TileHighlightData::window_number
WindowNumber window_number
The WindowNumber of the window that is responsible for the selection mode.
Definition tilehighlight_type.h:69
Train
'Train' is either a loco or a wagon.
Definition train.h:91
Train::GetDisplayImageWidth
int GetDisplayImageWidth(Point *offset=nullptr) const
Get the width of a train vehicle image in the GUI.
Definition train_cmd.cpp:460
VehicleCache::cached_max_speed
uint16_t cached_max_speed
Maximum speed of the consist (minimum of the max speed of all vehicles in the consist).
Definition vehicle_base.h:93
VehicleDefaultSettings
Default settings for vehicles.
Definition settings_type.h:601
VehicleDefaultSettings::servint_aircraft
uint16_t servint_aircraft
service interval for aircraft
Definition settings_type.h:605
VehicleDefaultSettings::servint_roadveh
uint16_t servint_roadveh
service interval for road vehicles
Definition settings_type.h:604
VehicleDefaultSettings::servint_ships
uint16_t servint_ships
service interval for ships
Definition settings_type.h:606
VehicleDefaultSettings::servint_trains
uint16_t servint_trains
service interval for trains
Definition settings_type.h:603
VehicleDetailsWindow
Class for managing the vehicle details window.
Definition vehicle_gui.cpp:2405
VehicleDetailsWindow::OnTooltip
bool OnTooltip(Point pt, WidgetID widget, TooltipCloseCondition close_cond) override
Event to display a custom tooltip.
Definition vehicle_gui.cpp:2753
VehicleDetailsWindow::GetRoadVehDetailsHeight
uint GetRoadVehDetailsHeight(const Vehicle *v)
Gets the desired height for the road vehicle details panel.
Definition vehicle_gui.cpp:2450
VehicleDetailsWindow::DrawVehicleDetails
static void DrawVehicleDetails(const Vehicle *v, const Rect &r, int vscroll_pos, uint vscroll_cap, TrainDetailsWindowTabs det_tab)
Draw the details for the given vehicle at the position of the Details windows.
Definition vehicle_gui.cpp:2559
VehicleDetailsWindow::OnPaint
void OnPaint() override
Repaint vehicle details window.
Definition vehicle_gui.cpp:2684
VehicleDetailsWindow::IsVehicleServiceIntervalEnabled
static bool IsVehicleServiceIntervalEnabled(const VehicleType vehicle_type, CompanyID company_id)
Checks whether service interval is enabled for the vehicle.
Definition vehicle_gui.cpp:2536
VehicleDetailsWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition vehicle_gui.cpp:2426
VehicleDetailsWindow::UpdateWidgetSize
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
Definition vehicle_gui.cpp:2466
VehicleDetailsWindow::DrawWidget
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition vehicle_gui.cpp:2577
VehicleDetailsWindow::OnResize
void OnResize() override
Called after the window got resized.
Definition vehicle_gui.cpp:2786
VehicleDetailsWindow::OnClick
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition vehicle_gui.cpp:2708
VehicleDetailsWindow::VehicleDetailsWindow
VehicleDetailsWindow(WindowDesc &desc, WindowNumber window_number)
Initialize a newly created vehicle details window.
Definition vehicle_gui.cpp:2410
VehicleDetailsWindow::tab
TrainDetailsWindowTabs tab
For train vehicles: which tab is displayed.
Definition vehicle_gui.cpp:2406
VehicleDetailsWindow::GetWidgetString
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
Definition vehicle_gui.cpp:2570
VehicleDetailsWindow::OnDropdownSelect
void OnDropdownSelect(WidgetID widget, int index, int) override
A dropdown option associated to this window has been selected.
Definition vehicle_gui.cpp:2772
VehicleListIdentifier
The information about a vehicle list.
Definition vehiclelist.h:32
VehicleListIdentifier::type
VehicleListType type
The type of vehicle list.
Definition vehiclelist.h:33
VehicleListIdentifier::company
CompanyID company
The company associated with this list.
Definition vehiclelist.h:35
VehicleListIdentifier::ToWindowNumber
WindowNumber ToWindowNumber() const
Pack a VehicleListIdentifier in 32 bits so it can be used as unique WindowNumber.
Definition vehiclelist.cpp:23
VehicleListIdentifier::vtype
VehicleType vtype
The vehicle type associated with this list.
Definition vehiclelist.h:34
VehicleListWindow
Window for the (old) vehicle listing.
Definition vehicle_gui.cpp:1896
VehicleListWindow::OnMouseLoop
void OnMouseLoop() override
Called for every mouse loop run, which is at least once per (game) tick.
Definition vehicle_gui.cpp:2082
VehicleListWindow::OnResize
void OnResize() override
Called after the window got resized.
Definition vehicle_gui.cpp:2224
VehicleListWindow::GetWidgetString
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
Definition vehicle_gui.cpp:2000
VehicleListWindow::OnPaint
void OnPaint() override
The window must be repainted.
Definition vehicle_gui.cpp:2053
VehicleListWindow::UpdateWidgetSize
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
Definition vehicle_gui.cpp:1947
VehicleListWindow::OnDropdownSelect
void OnDropdownSelect(WidgetID widget, int index, int) override
A dropdown option associated to this window has been selected.
Definition vehicle_gui.cpp:2174
VehicleListWindow::CaptionPlanes
CaptionPlanes
Enumeration of planes of the title row at the top.
Definition vehicle_gui.cpp:1905
VehicleListWindow::BP_SHARED_ORDERS
@ BP_SHARED_ORDERS
Show the normal caption.
Definition vehicle_gui.cpp:1907
VehicleListWindow::BP_NORMAL
@ BP_NORMAL
Show shared orders caption and buttons.
Definition vehicle_gui.cpp:1906
VehicleListWindow::OnGameTick
void OnGameTick() override
Called once per (game) tick.
Definition vehicle_gui.cpp:2214
VehicleListWindow::DrawWidget
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition vehicle_gui.cpp:2039
VehicleListWindow::OnClick
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition vehicle_gui.cpp:2090
VehicleListWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition vehicle_gui.cpp:2234
VehicleListWindow::ButtonPlanes
ButtonPlanes
Enumeration of planes of the button row at the bottom.
Definition vehicle_gui.cpp:1899
VehicleListWindow::BP_HIDE_BUTTONS
@ BP_HIDE_BUTTONS
Show the empty panel.
Definition vehicle_gui.cpp:1901
VehicleListWindow::BP_SHOW_BUTTONS
@ BP_SHOW_BUTTONS
Show the buttons.
Definition vehicle_gui.cpp:1900
VehicleSettings::roadveh_acceleration_model
uint8_t roadveh_acceleration_model
realistic acceleration for road vehicles
Definition settings_type.h:521
VehicleSettings::train_acceleration_model
uint8_t train_acceleration_model
realistic acceleration for trains
Definition settings_type.h:520
VehicleSpriteSeq
Sprite sequence for a vehicle part.
Definition vehicle_base.h:102
VehicleSpriteSeq::IsValid
bool IsValid() const
Check whether the sequence contains any sprites.
Definition vehicle_base.h:114
VehicleSpriteSeq::GetBounds
void GetBounds(Rect *bounds) const
Determine shared bounds of all sprites.
Definition vehicle.cpp:114
VehicleSpriteSeq::Set
void Set(SpriteID sprite)
Assign a single sprite to the sequence.
Definition vehicle_base.h:130
VehicleViewWindow
Window manager class for viewing a vehicle.
Definition vehicle_gui.cpp:2957
VehicleViewWindow::Close
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
Definition vehicle_gui.cpp:3053
VehicleViewWindow::OnResize
void OnResize() override
Called after the window got resized.
Definition vehicle_gui.cpp:3346
VehicleViewWindow::ShowNewGRFInspectWindow
void ShowNewGRFInspectWindow() const override
Show the NewGRF inspection window.
Definition vehicle_gui.cpp:3400
VehicleViewWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition vehicle_gui.cpp:3384
VehicleViewWindow::SelectPlane
void SelectPlane(PlaneSelections plane)
Display a plane in the window.
Definition vehicle_gui.cpp:2976
VehicleViewWindow::PlaneSelections
PlaneSelections
Display planes available in the vehicle view window.
Definition vehicle_gui.cpp:2960
VehicleViewWindow::SEL_RT_BASEPLANE
@ SEL_RT_BASEPLANE
First plane of the WID_VV_SELECT_REFIT_TURN stacked widget.
Definition vehicle_gui.cpp:2968
VehicleViewWindow::SEL_RT_TURN_AROUND
@ SEL_RT_TURN_AROUND
Display 'turn around' button in WID_VV_SELECT_REFIT_TURN stacked widget.
Definition vehicle_gui.cpp:2965
VehicleViewWindow::SEL_DC_BASEPLANE
@ SEL_DC_BASEPLANE
First plane of the WID_VV_SELECT_DEPOT_CLONE stacked widget.
Definition vehicle_gui.cpp:2967
VehicleViewWindow::SEL_RT_REFIT
@ SEL_RT_REFIT
Display 'refit' button in WID_VV_SELECT_REFIT_TURN stacked widget.
Definition vehicle_gui.cpp:2964
VehicleViewWindow::SEL_DC_GOTO_DEPOT
@ SEL_DC_GOTO_DEPOT
Display 'goto depot' button in WID_VV_SELECT_DEPOT_CLONE stacked widget.
Definition vehicle_gui.cpp:2961
VehicleViewWindow::SEL_DC_CLONE
@ SEL_DC_CLONE
Display 'clone vehicle' button in WID_VV_SELECT_DEPOT_CLONE stacked widget.
Definition vehicle_gui.cpp:2962
VehicleViewWindow::GetWidgetString
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
Definition vehicle_gui.cpp:3114
VehicleViewWindow::OnMouseOver
void OnMouseOver(Point pt, WidgetID widget) override
The mouse is currently moving over the window or has just moved outside of the window.
Definition vehicle_gui.cpp:3329
VehicleViewWindow::OnClick
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition vehicle_gui.cpp:3221
VehicleViewWindow::UpdateWidgetSize
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
Definition vehicle_gui.cpp:3062
VehicleViewWindow::OnQueryTextFinished
void OnQueryTextFinished(std::optional< std::string > str) override
The query window opened from this window has closed.
Definition vehicle_gui.cpp:3322
VehicleViewWindow::OnPaint
void OnPaint() override
The window must be repainted.
Definition vehicle_gui.cpp:3084
VehicleViewWindow::OnHotkey
EventState OnHotkey(int hotkey) override
A hotkey has been pressed.
Definition vehicle_gui.cpp:3308
VehicleViewWindow::DrawWidget
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition vehicle_gui.cpp:3201
VehicleViewWindow::OnMouseWheel
void OnMouseWheel(int wheel, WidgetID widget) override
The mouse wheel has been turned.
Definition vehicle_gui.cpp:3338
VehicleViewWindow::IsNewGRFInspectable
bool IsNewGRFInspectable() const override
Is the data related to this window NewGRF inspectable?
Definition vehicle_gui.cpp:3395
Vehicle
Vehicle data structure.
Definition vehicle_base.h:205
Vehicle::GetDisplayProfitThisYear
Money GetDisplayProfitThisYear() const
Gets the profit vehicle had this year.
Definition vehicle_base.h:572
Vehicle::engine_type
EngineID engine_type
The type of engine used for this vehicle.
Definition vehicle_base.h:278
Vehicle::GetDisplaySpeed
virtual int GetDisplaySpeed() const
Gets the speed in km-ish/h that can be sent into string parameters for string processing.
Definition vehicle_base.h:479
Vehicle::z_pos
int32_t z_pos
z coordinate.
Definition vehicle_base.h:267
Vehicle::GetEngine
const Engine * GetEngine() const
Retrieves the engine of the vehicle.
Definition vehicle.cpp:718
Vehicle::IsStoppedInDepot
bool IsStoppedInDepot() const
Check whether the vehicle is in the depot and stopped.
Definition vehicle_base.h:515
Vehicle::GetNextArticulatedPart
Vehicle * GetNextArticulatedPart() const
Get the next part of an articulated engine.
Definition vehicle_base.h:941
Vehicle::IsChainInDepot
virtual bool IsChainInDepot() const
Check whether the whole vehicle chain is in the depot.
Definition vehicle_base.h:509
Vehicle::date_of_last_service
TimerGameEconomy::Date date_of_last_service
Last economy date the vehicle had a service at a depot.
Definition vehicle_base.h:256
Vehicle::cargo_cap
uint16_t cargo_cap
total capacity
Definition vehicle_base.h:299
Vehicle::GetFirstEnginePart
Vehicle * GetFirstEnginePart()
Get the first part of an articulated engine.
Definition vehicle_base.h:951
Vehicle::subtype
uint8_t subtype
subtype (Filled with values from AircraftSubType/DisasterSubType/EffectVehicleType/GroundVehicleSubty...
Definition vehicle_base.h:310
Vehicle::HasArticulatedPart
bool HasArticulatedPart() const
Check if an engine has an articulated part.
Definition vehicle_base.h:931
Vehicle::breakdown_ctr
uint8_t breakdown_ctr
Counter for managing breakdown events.
Definition vehicle_base.h:260
Vehicle::group_id
GroupID group_id
Index of group Pool array.
Definition vehicle_base.h:321
Vehicle::GetDisplayMaxSpeed
virtual int GetDisplayMaxSpeed() const
Gets the maximum speed in km-ish/h that can be sent into string parameters for string processing.
Definition vehicle_base.h:485
Vehicle::IsGroundVehicle
bool IsGroundVehicle() const
Check if the vehicle is a ground vehicle.
Definition vehicle_base.h:470
Vehicle::vehstatus
VehStates vehstatus
Status.
Definition vehicle_base.h:309
Vehicle::IsArticulatedPart
bool IsArticulatedPart() const
Check if the vehicle is an articulated part of an engine.
Definition vehicle_base.h:922
Vehicle::cargo_type
CargoType cargo_type
type of cargo this vehicle is carrying
Definition vehicle_base.h:297
Vehicle::GetNumManualOrders
VehicleOrderID GetNumManualOrders() const
Get the number of manually added orders this vehicle has.
Definition vehicle_base.h:711
Vehicle::First
Vehicle * First() const
Get the first vehicle of this vehicle chain.
Definition vehicle_base.h:600
Vehicle::current_order
Order current_order
The current order (+ status, like: loading)
Definition vehicle_base.h:311
Vehicle::Next
Vehicle * Next() const
Get the next vehicle of this vehicle.
Definition vehicle_base.h:587
Vehicle::y_pos
int32_t y_pos
y coordinate.
Definition vehicle_base.h:266
Vehicle::x_pos
int32_t x_pos
x coordinate.
Definition vehicle_base.h:265
Vehicle::GetGRF
const GRFFile * GetGRF() const
Retrieve the NewGRF the vehicle is tied to.
Definition vehicle.cpp:728
Vehicle::orders
OrderList * orders
Pointer to the order list for this vehicle.
Definition vehicle_base.h:314
Vehicle::GetDisplayMinPowerToWeight
uint32_t GetDisplayMinPowerToWeight() const
Calculates the minimum power-to-weight ratio using the maximum weight of the ground vehicle.
Definition vehicle.cpp:3247
Vehicle::value
Money value
Value of the vehicle.
Definition vehicle_base.h:236
Vehicle::InvalidateNewGRFCache
void InvalidateNewGRFCache()
Invalidates cached NewGRF variables.
Definition vehicle_base.h:450
Vehicle::vcache
VehicleCache vcache
Cache of often used vehicle values.
Definition vehicle_base.h:319
Vehicle::GetGRFID
uint32_t GetGRFID() const
Retrieve the GRF ID of the NewGRF the vehicle is tied to.
Definition vehicle.cpp:738
Vehicle::GetGroundVehicleCache
GroundVehicleCache * GetGroundVehicleCache()
Access the ground vehicle cache of the vehicle.
Definition vehicle.cpp:3143
Vehicle::IsPrimaryVehicle
virtual bool IsPrimaryVehicle() const
Whether this is the primary vehicle in the chain.
Definition vehicle_base.h:432
Vehicle::GetDisplayProfitLastYear
Money GetDisplayProfitLastYear() const
Gets the profit vehicle had last year.
Definition vehicle_base.h:578
Vehicle::cur_speed
uint16_t cur_speed
current speed
Definition vehicle_base.h:283
Vehicle::cargo_subtype
uint8_t cargo_subtype
Used for livery refits (NewGRF variations)
Definition vehicle_base.h:298
Vehicle::age
TimerGameCalendar::Date age
Age in calendar days.
Definition vehicle_base.h:253
Vehicle::IsWaitingForUnbunching
bool IsWaitingForUnbunching() const
Check whether a vehicle inside a depot is waiting for unbunching.
Definition vehicle.cpp:2533
Vehicle::GetDisplayRunningCost
Money GetDisplayRunningCost() const
Gets the running cost of a vehicle that can be sent into string parameters for string processing.
Definition vehicle_base.h:566
Vehicle::breakdowns_since_last_service
uint8_t breakdowns_since_last_service
Counter for the amount of breakdowns.
Definition vehicle_base.h:262
Vehicle::max_age
TimerGameCalendar::Date max_age
Maximum age.
Definition vehicle_base.h:255
Vehicle::reliability
uint16_t reliability
Reliability.
Definition vehicle_base.h:258
Vehicle::FirstShared
Vehicle * FirstShared() const
Get the first vehicle of this vehicle chain.
Definition vehicle_base.h:693
Vehicle::Previous
Vehicle * Previous() const
Get the previous vehicle of this vehicle.
Definition vehicle_base.h:594
Vehicle::PlayLeaveStationSound
virtual void PlayLeaveStationSound(bool force=false) const
Play the sound associated with leaving the station.
Definition vehicle_base.h:427
Vehicle::IsInDepot
virtual bool IsInDepot() const
Check whether the vehicle is in the depot.
Definition vehicle_base.h:503
Vehicle::tile
TileIndex tile
Current tile index.
Definition vehicle_base.h:225
Vehicle::owner
Owner owner
Which company owns the vehicle?
Definition vehicle_base.h:270
Vehicle::unitnumber
UnitID unitnumber
unit number, for display purposes only
Definition vehicle_base.h:281
Vehicle::GetImage
virtual void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const
Gets the sprite to show for the given direction.
Definition vehicle_base.h:441
WindowDesc
High level window description.
Definition window_gui.h:168
WindowNumber
Number to differentiate different windows of the same class.
Definition window_type.h:760
Window
Data structure for an opened window.
Definition window_gui.h:274
Window::ReInit
void ReInit(int rx=0, int ry=0, bool reposition=false)
Re-initialize a window, and optionally change its size.
Definition window.cpp:980
Window::Close
virtual void Close(int data=0)
Hide the window and all its child windows, and mark them for a later deletion.
Definition window.cpp:1104
Window::SortButtonWidth
static int SortButtonWidth()
Get width of up/down arrow of sort button state.
Definition widget.cpp:833
Window::FinishInitNested
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1809
Window::DrawWidgets
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:784
Window::InvalidateData
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing)
Definition window.cpp:3237
Window::parent
Window * parent
Parent window.
Definition window_gui.h:329
Window::SetWidgetDirty
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:558
Window::viewport
std::unique_ptr< ViewportData > viewport
Pointer to viewport data, if present.
Definition window_gui.h:319
Window::GetWidgetString
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
Definition window.cpp:506
Window::DrawSortButtonState
void DrawSortButtonState(WidgetID widget, SortButtonState state) const
Draw a sort button's up or down arrow symbol.
Definition widget.cpp:816
Window::CloseChildWindows
void CloseChildWindows(WindowClass wc=WC_INVALID) const
Close all children a window might have in a head-recursive manner.
Definition window.cpp:1077
Window::resize
ResizeInfo resize
Resize information.
Definition window_gui.h:315
Window::OnVehicleSelect
virtual bool OnVehicleSelect(const struct Vehicle *v)
The user clicked on a vehicle while HT_VEHICLE has been set.
Definition window_gui.h:809
Window::SetWidgetsDisabledState
void SetWidgetsDisabledState(bool disab_stat, Args... widgets)
Sets the enabled/disabled status of a list of widgets.
Definition window_gui.h:516
Window::CreateNestedTree
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1799
Window::SetWidgetsLoweredState
void SetWidgetsLoweredState(bool lowered_stat, Args... widgets)
Sets the lowered/raised status of a list of widgets.
Definition window_gui.h:527
Window::owner
Owner owner
The owner of the content shown in this window. Company colour is acquired from this variable.
Definition window_gui.h:317
Window::SetWidgetLoweredState
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition window_gui.h:442
Window::left
int left
x position of left edge of the window
Definition window_gui.h:310
Window::LowerWidget
void LowerWidget(WidgetID widget_index)
Marks a widget as lowered.
Definition window_gui.h:461
Window::flags
WindowFlags flags
Window flags.
Definition window_gui.h:301
Window::GetScrollbar
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition window.cpp:315
Window::OnHotkey
virtual EventState OnHotkey(int hotkey)
A hotkey has been pressed.
Definition window.cpp:572
Window::SetWidgetDisabledState
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:382
Window::height
int height
Height of the window (number of pixels down in y direction)
Definition window_gui.h:313
Window::width
int width
width of the window (number of pixels to the right in x direction)
Definition window_gui.h:312
Window::window_number
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:303
textbuf_gui.h
Stuff related to the text buffer GUI.
TE_RISING
@ TE_RISING
Make the text effect slowly go upwards.
Definition texteff.hpp:22
INVALID_TILE
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95
tilehighlight_func.h
Functions related to tile highlights.
SetObjectToPlaceWnd
void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Window *w)
Change the cursor and mouse click/drag handling to a mode for performing special operations like tile...
Definition viewport.cpp:3510
HT_DRAG
@ HT_DRAG
dragging items in the depot windows
Definition tilehighlight_type.h:24
HT_VEHICLE
@ HT_VEHICLE
vehicle is accepted as target as well (bitmask)
Definition tilehighlight_type.h:27
timetable.h
Functions related to time tabling.
ShowTimetableWindow
void ShowTimetableWindow(const Vehicle *v)
Show the timetable for a given vehicle.
Definition timetable_gui.cpp:856
train.h
Base for the train class.
Stuck
@ Stuck
Train can't get a path reservation.
Definition train.h:32
TFP_SIGNAL
@ TFP_SIGNAL
Ignore next signal, after the signal ignore being stuck.
Definition train.h:41
train_cmd.h
Command definitions related to trains.
DrawTrainImage
void DrawTrainImage(const Train *v, const Rect &r, VehicleID selection, EngineImageType image_type, int skip, VehicleID drag_dest)
Draws an image of a whole train.
Definition train_gui.cpp:98
GetVehiclePalette
PaletteID GetVehiclePalette(const Vehicle *v)
Get the colour map for a vehicle.
Definition vehicle.cpp:2133
GetVehicleSet
void GetVehicleSet(VehicleSet &set, Vehicle *v, uint8_t num_vehicles)
Calculates the set of vehicles that will be affected by a given selection.
Definition vehicle.cpp:3206
VehState::Crashed
@ Crashed
Vehicle is crashed.
VehState::Stopped
@ Stopped
Vehicle is stopped by the player.
vehicle_cmd.h
Command definitions for vehicles.
vehicle_func.h
Functions related to vehicles.
VEHICLE_PROFIT_MIN_AGE
static const TimerGameEconomy::Date VEHICLE_PROFIT_MIN_AGE
Only vehicles older than this have a meaningful profit.
Definition vehicle_func.h:37
VEHICLE_PROFIT_THRESHOLD
static const Money VEHICLE_PROFIT_THRESHOLD
Threshold for a vehicle to be considered making good profit.
Definition vehicle_func.h:38
DrawAircraftDetails
void DrawAircraftDetails(const Aircraft *v, const Rect &r)
Draw the details for the given vehicle at the given position.
Definition aircraft_gui.cpp:29
CargoFilter
static bool CargoFilter(const GUIVehicleGroup *vehgroup, const CargoType cargo_type)
Check whether a vehicle can carry a specific cargo.
Definition vehicle_gui.cpp:321
GetSingleVehicleWidth
int GetSingleVehicleWidth(const Vehicle *v, EngineImageType image_type)
Get the width of a vehicle (part) in pixels.
Definition vehicle_gui.cpp:3508
DrawShipDetails
void DrawShipDetails(const Vehicle *v, const Rect &r)
Draw the details for the given vehicle at the given position.
Definition ship_gui.cpp:62
GetVehicleWidth
int GetVehicleWidth(const Vehicle *v, EngineImageType image_type)
Get the width of a vehicle (including all parts of the consist) in pixels.
Definition vehicle_gui.cpp:3532
GetCargoSubtypeText
StringID GetCargoSubtypeText(const Vehicle *v)
Get the cargo subtype text from NewGRF for the vehicle details window.
Definition vehicle_gui.cpp:1387
_train_view_desc
static WindowDesc _train_view_desc(WDP_AUTO, "view_vehicle_train", 250, 134, WC_VEHICLE_VIEW, WC_NONE, {}, _nested_vehicle_view_widgets, &VehicleViewWindow::hotkeys)
Vehicle view window descriptor for trains.
ChangeVehicleWindow
static void ChangeVehicleWindow(WindowClass window_class, VehicleID from_index, VehicleID to_index)
Assign a vehicle window a new vehicle.
Definition vehicle_gui.cpp:1566
IsVehicleRefittable
static bool IsVehicleRefittable(const Vehicle *v)
Checks whether the vehicle may be refitted at the moment.
Definition vehicle_gui.cpp:2945
_nested_train_vehicle_details_widgets
static constexpr std::initializer_list< NWidgetPart > _nested_train_vehicle_details_widgets
Train details widgets.
Definition vehicle_gui.cpp:2350
CcBuildPrimaryVehicle
void CcBuildPrimaryVehicle(Commands, const CommandCost &result, VehicleID new_veh_id, uint, uint16_t, CargoArray)
This is the Callback method after the construction attempt of a primary vehicle.
Definition vehicle_gui.cpp:3495
GetUnitNumberDigits
uint GetUnitNumberDigits(VehicleList &vehicles)
Get the number of digits the biggest unit number of a set of vehicles has.
Definition vehicle_gui.cpp:209
ShowVehicleViewWindow
void ShowVehicleViewWindow(const Vehicle *v)
Shows the vehicle view window of the given vehicle.
Definition vehicle_gui.cpp:3432
_vehicle_msg_translation_table
static const StringID _vehicle_msg_translation_table[][4]
Command codes for the shared buttons indexed by VehicleCommandTranslation and vehicle type.
Definition vehicle_gui.cpp:2895
CountDigitsForAllocatingSpace
uint CountDigitsForAllocatingSpace(uint number)
Get the number of digits of space required for the given number.
Definition vehicle_gui.cpp:190
MAX_REFIT_CYCLE
static const uint MAX_REFIT_CYCLE
Maximum number of refit cycles we try, to prevent infinite loops.
Definition vehicle_gui.cpp:589
VehicleCommandTranslation
VehicleCommandTranslation
Command indices for the _vehicle_command_translation_table.
Definition vehicle_gui.cpp:2888
ShowRefitOptionsList
uint ShowRefitOptionsList(int left, int right, int y, EngineID engine)
Display list of cargo types of the engine, for the purchase information window.
Definition vehicle_gui.cpp:1358
DrawVehicleImage
void DrawVehicleImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type, int skip)
Draws an image of a vehicle chain.
Definition vehicle_gui.cpp:1710
DrawTrainDetails
void DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16_t vscroll_cap, TrainDetailsWindowTabs det_tab)
Draw the details for the given vehicle at the given position.
Definition train_gui.cpp:354
_vehicle_view_zoom_levels
static const ZoomLevel _vehicle_view_zoom_levels[]
Zoom levels for vehicle views indexed by vehicle type.
Definition vehicle_gui.cpp:2875
_vehicle_view_desc
static WindowDesc _vehicle_view_desc(WDP_AUTO, "view_vehicle", 250, 116, WC_VEHICLE_VIEW, WC_NONE, {}, _nested_vehicle_view_widgets, &VehicleViewWindow::hotkeys)
Vehicle view window descriptor for all vehicles but trains.
DrawVehicleProfitButton
static void DrawVehicleProfitButton(TimerGameEconomy::Date age, Money display_profit_last_year, uint num_vehicles, int x, int y)
draw the vehicle profit button in the vehicle list window.
Definition vehicle_gui.cpp:571
GetUnitNumberWidth
static int GetUnitNumberWidth(int digits)
Get width required for the formatted unit number display.
Definition vehicle_gui.cpp:1746
_nested_vehicle_view_widgets
static constexpr std::initializer_list< NWidgetPart > _nested_vehicle_view_widgets
Vehicle view widgets.
Definition vehicle_gui.cpp:2823
CargoFilterSingle
static bool CargoFilterSingle(const Vehicle *v, const CargoType cargo_type)
Check whether a single vehicle should pass the filter.
Definition vehicle_gui.cpp:281
_train_vehicle_details_desc
static WindowDesc _train_vehicle_details_desc(WDP_AUTO, "view_vehicle_details_train", 405, 178, WC_VEHICLE_DETAILS, WC_VEHICLE_VIEW, {}, _nested_train_vehicle_details_widgets)
Vehicle details window descriptor.
GetBestFittingSubType
uint8_t GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoType dest_cargo_type)
Get the best fitting subtype when 'cloning'/'replacing' v_from with v_for.
Definition vehicle_gui.cpp:600
ChangeVehicleViewWindow
void ChangeVehicleViewWindow(VehicleID from_index, VehicleID to_index)
Report a change in vehicle IDs (due to autoreplace) to affected vehicle windows.
Definition vehicle_gui.cpp:1589
GetTrainDetailsWndVScroll
int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab)
Determines the number of lines in the train details window.
Definition train_gui.cpp:320
VehicleClicked
bool VehicleClicked(const Vehicle *v)
Dispatch a "vehicle selected" event if any window waits for it.
Definition vehicle_gui.cpp:3442
GetVehicleListHeight
uint GetVehicleListHeight(VehicleType type, uint divisor)
Get the height of a vehicle in the vehicle list GUIs.
Definition vehicle_gui.cpp:1727
StartStopVehicle
void StartStopVehicle(const Vehicle *v, bool texteffect)
Executes CMD_START_STOP_VEHICLE for given vehicle.
Definition vehicle_gui.cpp:2938
SetMouseCursorVehicle
void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type)
Set the mouse cursor to look like a vehicle.
Definition vehicle_gui.cpp:3550
_nontrain_vehicle_details_desc
static WindowDesc _nontrain_vehicle_details_desc(WDP_AUTO, "view_vehicle_details", 405, 113, WC_VEHICLE_DETAILS, WC_VEHICLE_VIEW, {}, _nested_nontrain_vehicle_details_widgets)
Vehicle details window descriptor for other vehicles than a train.
ShowVehicleRefitWindow
void ShowVehicleRefitWindow(const Vehicle *v, VehicleOrderID order, Window *parent, bool auto_refit)
Show the refit window for a vehicle.
Definition vehicle_gui.cpp:1350
DrawCargoIconOverlays
void DrawCargoIconOverlays(std::span< const CargoIconOverlay > overlays, int y)
Draw a list of cargo icon overlays.
Definition vehicle_gui.cpp:401
AddCargoIconOverlay
void AddCargoIconOverlay(std::vector< CargoIconOverlay > &overlays, int x, int width, const Vehicle *v)
Add a cargo icon to the list of overlays.
Definition vehicle_gui.cpp:349
_nested_nontrain_vehicle_details_widgets
static constexpr std::initializer_list< NWidgetPart > _nested_nontrain_vehicle_details_widgets
Vehicle details widgets (other than train).
Definition vehicle_gui.cpp:2327
VehicleIndividualToGroupSorterWrapper
static bool VehicleIndividualToGroupSorterWrapper(GUIVehicleGroup const &a, GUIVehicleGroup const &b)
Wrapper to convert a VehicleIndividualSortFunction to a VehicleGroupSortFunction.
Definition vehicle_gui.cpp:77
DrawCargoIconOverlay
void DrawCargoIconOverlay(int x, int y, CargoType cargo_type)
Draw a cargo icon overlaying an existing sprite, with a black contrast outline.
Definition vehicle_gui.cpp:372
ShowCargoIconOverlay
bool ShowCargoIconOverlay()
Test if cargo icon overlays should be drawn.
Definition vehicle_gui.cpp:337
DrawVehicleRefitWindow
static void DrawVehicleRefitWindow(const RefitOptions &refits, const RefitOption *sel, uint pos, uint rows, uint delta, const Rect &r)
Draw the list of available refit options for a consist and highlight the selected refit option (if an...
Definition vehicle_gui.cpp:691
ShowVehicleDetailsWindow
static void ShowVehicleDetailsWindow(const Vehicle *v)
Shows the vehicle details window of the given vehicle.
Definition vehicle_gui.cpp:2812
DrawRoadVehDetails
void DrawRoadVehDetails(const Vehicle *v, const Rect &r)
Draw the details for the given vehicle at the given position.
Definition roadveh_gui.cpp:29
RefitOptions
std::map< CargoType, std::vector< RefitOption >, CargoTypeComparator > RefitOptions
Available refit options (subtype and string) associated with each cargo type.
Definition vehicle_gui.cpp:680
CcStartStopVehicle
void CcStartStopVehicle(Commands, const CommandCost &result, VehicleID veh_id, bool)
This is the Callback method after attempting to start/stop a vehicle.
Definition vehicle_gui.cpp:2921
VIWD_CONSIST_CHANGED
@ VIWD_CONSIST_CHANGED
Vehicle composition was changed.
Definition vehicle_gui.h:37
VIWD_AUTOREPLACE
@ VIWD_AUTOREPLACE
Autoreplace replaced the vehicle.
Definition vehicle_gui.h:38
GetVehicleHeight
uint GetVehicleHeight(VehicleType type)
Get the height of a single vehicle in the GUIs.
Definition vehicle_gui.h:74
TrainDetailsWindowTabs
TrainDetailsWindowTabs
The tabs in the train details window.
Definition vehicle_gui.h:25
TDW_TAB_CAPACITY
@ TDW_TAB_CAPACITY
Tab with cargo capacity of the vehicles.
Definition vehicle_gui.h:28
TDW_TAB_TOTALS
@ TDW_TAB_TOTALS
Tab with sum of total cargo transported.
Definition vehicle_gui.h:29
TDW_TAB_INFO
@ TDW_TAB_INFO
Tab with name and value of the vehicles.
Definition vehicle_gui.h:27
TDW_TAB_CARGO
@ TDW_TAB_CARGO
Tab with cargo carried by the vehicles.
Definition vehicle_gui.h:26
vehicle_gui_base.h
Functions/classes shared between the different vehicle list GUIs.
EngineImageType
EngineImageType
Visualisation contexts of vehicles and engines.
Definition vehicle_type.h:74
EIT_IN_DETAILS
@ EIT_IN_DETAILS
Vehicle drawn in vehicle details, refit window, ...
Definition vehicle_type.h:77
EIT_IN_LIST
@ EIT_IN_LIST
Vehicle drawn in vehicle list, group list, ...
Definition vehicle_type.h:78
VehicleType
VehicleType
Available vehicle types.
Definition vehicle_type.h:22
VEH_ROAD
@ VEH_ROAD
Road vehicle type.
Definition vehicle_type.h:26
VEH_AIRCRAFT
@ VEH_AIRCRAFT
Aircraft vehicle type.
Definition vehicle_type.h:28
VEH_SHIP
@ VEH_SHIP
Ship vehicle type.
Definition vehicle_type.h:27
VEH_TRAIN
@ VEH_TRAIN
Train vehicle type.
Definition vehicle_type.h:25
DepotCommandFlag::MassSend
@ MassSend
Tells that it's a mass send to depot command (type in VLW flag)
DepotCommandFlag::Service
@ Service
The vehicle will leave the depot right after arrival (service only)
MAX_LENGTH_VEHICLE_NAME_CHARS
static const uint MAX_LENGTH_VEHICLE_NAME_CHARS
The maximum length of a vehicle name in characters including '\0'.
Definition vehicle_type.h:62
WID_VR_MATRIX
@ WID_VR_MATRIX
Options to refit to.
Definition vehicle_widget.h:41
WID_VR_SCROLLBAR
@ WID_VR_SCROLLBAR
Scrollbar for the refit options.
Definition vehicle_widget.h:42
WID_VR_SHOW_HSCROLLBAR
@ WID_VR_SHOW_HSCROLLBAR
Selection widget for the horizontal scrollbar.
Definition vehicle_widget.h:38
WID_VR_VEHICLE_PANEL_DISPLAY
@ WID_VR_VEHICLE_PANEL_DISPLAY
Display with a representation of the vehicle to refit.
Definition vehicle_widget.h:37
WID_VR_HSCROLLBAR
@ WID_VR_HSCROLLBAR
Horizontal scrollbar or the vehicle display.
Definition vehicle_widget.h:39
WID_VR_REFIT
@ WID_VR_REFIT
Perform the refit.
Definition vehicle_widget.h:44
WID_VR_SELECT_HEADER
@ WID_VR_SELECT_HEADER
Header with question about the cargo to carry.
Definition vehicle_widget.h:40
WID_VR_INFO
@ WID_VR_INFO
Information about the currently selected refit option.
Definition vehicle_widget.h:43
WID_VR_CAPTION
@ WID_VR_CAPTION
Caption of window.
Definition vehicle_widget.h:36
WID_VL_SORT_BY_PULLDOWN
@ WID_VL_SORT_BY_PULLDOWN
Sort by dropdown list.
Definition vehicle_widget.h:73
WID_VL_START_ALL
@ WID_VL_START_ALL
Start all button.
Definition vehicle_widget.h:82
WID_VL_FILTER_BY_CARGO_SEL
@ WID_VL_FILTER_BY_CARGO_SEL
Cargo filter dropdown list panel selector.
Definition vehicle_widget.h:75
WID_VL_MANAGE_VEHICLES_DROPDOWN
@ WID_VL_MANAGE_VEHICLES_DROPDOWN
Manage vehicles dropdown list.
Definition vehicle_widget.h:80
WID_VL_HIDE_BUTTONS
@ WID_VL_HIDE_BUTTONS
Selection to hide the buttons.
Definition vehicle_widget.h:78
WID_VL_GROUP_BY_PULLDOWN
@ WID_VL_GROUP_BY_PULLDOWN
Group by dropdown list.
Definition vehicle_widget.h:71
WID_VL_AVAILABLE_VEHICLES
@ WID_VL_AVAILABLE_VEHICLES
Available vehicles.
Definition vehicle_widget.h:79
WID_VL_STOP_ALL
@ WID_VL_STOP_ALL
Stop all button.
Definition vehicle_widget.h:81
WID_VL_CAPTION_SELECTION
@ WID_VL_CAPTION_SELECTION
Selection for caption.
Definition vehicle_widget.h:68
WID_VL_FILTER_BY_CARGO
@ WID_VL_FILTER_BY_CARGO
Cargo filter dropdown list.
Definition vehicle_widget.h:74
WID_VL_SORT_ORDER
@ WID_VL_SORT_ORDER
Sort order.
Definition vehicle_widget.h:72
WID_VL_GROUP_ORDER
@ WID_VL_GROUP_ORDER
Group order.
Definition vehicle_widget.h:70
WID_VL_SCROLLBAR
@ WID_VL_SCROLLBAR
Scrollbar for the list.
Definition vehicle_widget.h:77
WID_VL_CAPTION
@ WID_VL_CAPTION
Caption of window (for non shared orders windows).
Definition vehicle_widget.h:66
WID_VL_LIST
@ WID_VL_LIST
List of the vehicles.
Definition vehicle_widget.h:76
WID_VL_CAPTION_SHARED_ORDERS
@ WID_VL_CAPTION_SHARED_ORDERS
Caption of window (for shared orders windows).
Definition vehicle_widget.h:67
WID_VL_ORDER_VIEW
@ WID_VL_ORDER_VIEW
Button to open order window (for shared orders windows).
Definition vehicle_widget.h:69
WID_VV_GOTO_DEPOT
@ WID_VV_GOTO_DEPOT
Order this vehicle to go to the depot.
Definition vehicle_widget.h:21
WID_VV_LOCATION
@ WID_VV_LOCATION
Center the main view on this vehicle.
Definition vehicle_widget.h:19
WID_VV_TURN_AROUND
@ WID_VV_TURN_AROUND
Turn this vehicle around.
Definition vehicle_widget.h:28
WID_VV_SELECT_DEPOT_CLONE
@ WID_VV_SELECT_DEPOT_CLONE
Selection widget between 'goto depot', and 'clone vehicle' buttons.
Definition vehicle_widget.h:26
WID_VV_FORCE_PROCEED
@ WID_VV_FORCE_PROCEED
Force this vehicle to pass a signal at danger.
Definition vehicle_widget.h:29
WID_VV_RENAME
@ WID_VV_RENAME
Rename vehicle.
Definition vehicle_widget.h:18
WID_VV_ORDER_LOCATION
@ WID_VV_ORDER_LOCATION
Center the main view on the order's target location.
Definition vehicle_widget.h:20
WID_VV_SHOW_ORDERS
@ WID_VV_SHOW_ORDERS
Show the orders of this vehicle.
Definition vehicle_widget.h:23
WID_VV_CLONE
@ WID_VV_CLONE
Clone this vehicle.
Definition vehicle_widget.h:25
WID_VV_CAPTION
@ WID_VV_CAPTION
Caption of window.
Definition vehicle_widget.h:15
WID_VV_REFIT
@ WID_VV_REFIT
Open the refit window.
Definition vehicle_widget.h:22
WID_VV_START_STOP
@ WID_VV_START_STOP
Start or stop this vehicle, and show information about the current state.
Definition vehicle_widget.h:17
WID_VV_SELECT_REFIT_TURN
@ WID_VV_SELECT_REFIT_TURN
Selection widget between 'refit' and 'turn around' buttons.
Definition vehicle_widget.h:27
WID_VV_SHOW_DETAILS
@ WID_VV_SHOW_DETAILS
Show details of this vehicle.
Definition vehicle_widget.h:24
WID_VV_VIEWPORT
@ WID_VV_VIEWPORT
Viewport widget.
Definition vehicle_widget.h:16
WID_VV_HONK_HORN
@ WID_VV_HONK_HORN
Honk the vehicles horn (not drawn on UI, only used for hotkey).
Definition vehicle_widget.h:31
WID_VV_FORCE_PROCEED_SEL
@ WID_VV_FORCE_PROCEED_SEL
Container for 'force proceed' button, which can be hidden.
Definition vehicle_widget.h:30
WID_VD_DECREASE_SERVICING_INTERVAL
@ WID_VD_DECREASE_SERVICING_INTERVAL
Decrease the servicing interval.
Definition vehicle_widget.h:52
WID_VD_CAPTION
@ WID_VD_CAPTION
Caption of window.
Definition vehicle_widget.h:49
WID_VD_SERVICE_INTERVAL_DROPDOWN
@ WID_VD_SERVICE_INTERVAL_DROPDOWN
Dropdown to select default/days/percent service interval.
Definition vehicle_widget.h:53
WID_VD_INCREASE_SERVICING_INTERVAL
@ WID_VD_INCREASE_SERVICING_INTERVAL
Increase the servicing interval.
Definition vehicle_widget.h:51
WID_VD_MATRIX
@ WID_VD_MATRIX
List of details for trains.
Definition vehicle_widget.h:56
WID_VD_SERVICING_INTERVAL
@ WID_VD_SERVICING_INTERVAL
Information about the servicing interval.
Definition vehicle_widget.h:54
WID_VD_DETAILS_TRAIN_VEHICLES
@ WID_VD_DETAILS_TRAIN_VEHICLES
Show all parts of the train with their description.
Definition vehicle_widget.h:59
WID_VD_SCROLLBAR
@ WID_VD_SCROLLBAR
Scrollbar for train details.
Definition vehicle_widget.h:57
WID_VD_DETAILS_TOTAL_CARGO
@ WID_VD_DETAILS_TOTAL_CARGO
Show the capacity and carried cargo amounts aggregated per cargo of the train.
Definition vehicle_widget.h:61
WID_VD_TOP_DETAILS
@ WID_VD_TOP_DETAILS
Panel with generic details.
Definition vehicle_widget.h:50
WID_VD_MIDDLE_DETAILS
@ WID_VD_MIDDLE_DETAILS
Details for non-trains.
Definition vehicle_widget.h:55
WID_VD_DETAILS_CAPACITY_OF_EACH
@ WID_VD_DETAILS_CAPACITY_OF_EACH
Show the capacity of all train parts.
Definition vehicle_widget.h:60
WID_VD_DETAILS_CARGO_CARRIED
@ WID_VD_DETAILS_CARGO_CARRIED
Show carried cargo per part of the train.
Definition vehicle_widget.h:58
GenerateVehicleSortList
bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli)
Generate a list of vehicles based on window type.
Definition vehiclelist.cpp:70
VehicleList
std::vector< const Vehicle * > VehicleList
A list of vehicles.
Definition vehiclelist.h:68
VehicleListType
VehicleListType
Vehicle List type flags.
Definition vehiclelist.h:22
VL_STANDARD
@ VL_STANDARD
Index is the company.
Definition vehiclelist.h:23
VL_STATION_LIST
@ VL_STATION_LIST
Index is the station.
Definition vehiclelist.h:25
VL_DEPOT_LIST
@ VL_DEPOT_LIST
Index is the destination (station for hangar of aircraft, depot for others)
Definition vehiclelist.h:26
VL_SHARED_ORDERS
@ VL_SHARED_ORDERS
Index is the first vehicle of the shared orders.
Definition vehiclelist.h:24
ScrollMainWindowToTile
bool ScrollMainWindowToTile(TileIndex tile, bool instant)
Scrolls the viewport of the main window to a given location.
Definition viewport.cpp:2592
viewport_func.h
Functions related to (drawing on) viewports.
ZOOM_IN
@ ZOOM_IN
Zoom in (get more detailed view).
Definition viewport_type.h:81
ZOOM_OUT
@ ZOOM_OUT
Zoom out (get helicopter view).
Definition viewport_type.h:82
DrawFrameRect
void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags)
Draw frame rectangle.
Definition widget.cpp:307
ScaleGUITrad
static RectPadding ScaleGUITrad(const RectPadding &r)
Scale a RectPadding to GUI zoom level.
Definition widget.cpp:49
WWT_PUSHTXTBTN
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
Definition widget_type.h:105
WWT_INSET
@ WWT_INSET
Pressed (inset) panel, most commonly used as combo box text area.
Definition widget_type.h:40
WWT_PUSHBTN
@ WWT_PUSHBTN
Normal push-button (no toggle button) with custom drawing.
Definition widget_type.h:104
WWT_PUSHIMGBTN
@ WWT_PUSHIMGBTN
Normal push-button (no toggle button) with image caption.
Definition widget_type.h:106
WWT_PUSHARROWBTN
@ WWT_PUSHARROWBTN
Normal push-button (no toggle button) with arrow caption.
Definition widget_type.h:107
NWID_HORIZONTAL
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:66
WWT_TEXTBTN
@ WWT_TEXTBTN
(Toggle) Button with text
Definition widget_type.h:44
WWT_PANEL
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:39
WWT_STICKYBOX
@ WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition widget_type.h:57
WWT_MATRIX
@ WWT_MATRIX
Grid of rows and columns.
Definition widget_type.h:50
WWT_SHADEBOX
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition widget_type.h:55
WWT_CAPTION
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition widget_type.h:52
NWID_VSCROLLBAR
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition widget_type.h:76
NWID_VERTICAL
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:68
WWT_CLOSEBOX
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:60
NWID_HSCROLLBAR
@ NWID_HSCROLLBAR
Horizontal scrollbar.
Definition widget_type.h:75
WWT_RESIZEBOX
@ WWT_RESIZEBOX
Resize box (normally at bottom-right of a window)
Definition widget_type.h:59
WWT_DEFSIZEBOX
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition widget_type.h:56
NWID_VIEWPORT
@ NWID_VIEWPORT
Nested widget containing a viewport.
Definition widget_type.h:73
WWT_DROPDOWN
@ WWT_DROPDOWN
Drop down list.
Definition widget_type.h:61
WWT_DEBUGBOX
@ WWT_DEBUGBOX
NewGRF debug box (at top-right of a window, between WWT_CAPTION and WWT_SHADEBOX)
Definition widget_type.h:54
NWID_SELECTION
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:71
SZSP_HORIZONTAL
@ SZSP_HORIZONTAL
Display plane with zero size vertically, and filling and resizing horizontally.
Definition widget_type.h:508
SZSP_NONE
@ SZSP_NONE
Display plane with zero size in both directions (none filling and resizing).
Definition widget_type.h:509
EqualSize
@ EqualSize
Containers should keep all their (resizing) children equally large.
Definition widget_type.h:544
AWV_DECREASE
@ AWV_DECREASE
Arrow to the left or in case of RTL to the right.
Definition widget_type.h:20
AWV_INCREASE
@ AWV_INCREASE
Arrow to the right or in case of RTL to the left.
Definition widget_type.h:21
CloseWindowById
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition window.cpp:1195
GetMainWindow
Window * GetMainWindow()
Get the main window, i.e.
Definition window.cpp:1182
FindWindowById
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition window.cpp:1153
WindowDefaultFlag::Construction
@ Construction
This window is used for construction; close it whenever changing company.
FrameFlag::BorderOnly
@ BorderOnly
Draw border only, no background.
WindowFlag::DisableVpScroll
@ DisableVpScroll
Window does not do autoscroll,.
SBS_DOWN
@ SBS_DOWN
Sort ascending.
Definition window_gui.h:219
SBS_UP
@ SBS_UP
Sort descending.
Definition window_gui.h:220
WDP_AUTO
@ WDP_AUTO
Find a place automatically.
Definition window_gui.h:144
WidgetID
int WidgetID
Widget ID.
Definition window_type.h:20
EventState
EventState
State of handling an event.
Definition window_type.h:780
WindowClass
WindowClass
Window classes.
Definition window_type.h:49
WC_ROADVEH_LIST
@ WC_ROADVEH_LIST
Road vehicle list; Window numbers:
Definition window_type.h:319
WC_VEHICLE_ORDERS
@ WC_VEHICLE_ORDERS
Vehicle orders; Window numbers:
Definition window_type.h:217
WC_NONE
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:50
WC_SHIPS_LIST
@ WC_SHIPS_LIST
Ships list; Window numbers:
Definition window_type.h:325
WC_TRAINS_LIST
@ WC_TRAINS_LIST
Trains list; Window numbers:
Definition window_type.h:313
WC_VEHICLE_REFIT
@ WC_VEHICLE_REFIT
Vehicle refit; Window numbers:
Definition window_type.h:211
WC_DROPDOWN_MENU
@ WC_DROPDOWN_MENU
Drop down menu; Window numbers:
Definition window_type.h:161
WC_VEHICLE_DETAILS
@ WC_VEHICLE_DETAILS
Vehicle details; Window numbers:
Definition window_type.h:205
WC_VEHICLE_VIEW
@ WC_VEHICLE_VIEW
Vehicle view; Window numbers:
Definition window_type.h:344
WC_VEHICLE_TIMETABLE
@ WC_VEHICLE_TIMETABLE
Vehicle timetable; Window numbers:
Definition window_type.h:229
WC_AIRCRAFT_LIST
@ WC_AIRCRAFT_LIST
Aircraft list; Window numbers:
Definition window_type.h:331
zoom_func.h
Functions related to zooming.
ScaleSpriteTrad
int ScaleSpriteTrad(int value)
Scale traditional pixel dimensions to GUI zoom level, for drawing sprites.
Definition zoom_func.h:107
ScaleZoomGUI
ZoomLevel ScaleZoomGUI(ZoomLevel value)
Scale zoom level relative to GUI zoom.
Definition zoom_func.h:87
UnScaleGUI
int UnScaleGUI(int value)
Short-hand to apply GUI zoom level.
Definition zoom_func.h:77
ZoomLevel
ZoomLevel
All zoom levels we know.
Definition zoom_type.h:20
ZoomLevel::Ship
@ Ship
Default zoom level for the ship view.
ZoomLevel::RoadVehicle
@ RoadVehicle
Default zoom level for the road vehicle view.
ZoomLevel::Aircraft
@ Aircraft
Default zoom level for the aircraft view.
ZoomLevel::Train
@ Train
Default zoom level for the train view.