OpenTTD Source: src/vehicle_gui.cpp Source File

OpenTTD Source 13.1

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