OpenTTD Source: src/vehicle_gui.cpp Source File

OpenTTD Source 15.0-beta1

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