OpenTTD Source: src/depot_gui.cpp Source File

OpenTTD Source 15.0-beta1

depot_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 "train.h"
12#include "roadveh.h"
13#include "ship.h"
14#include "aircraft.h"
15#include "gui.h"
16#include "textbuf_gui.h"
17#include "viewport_func.h"
18#include "command_func.h"
19#include "depot_base.h"
20#include "spritecache.h"
21#include "strings_func.h"
22#include "vehicle_func.h"
23#include "company_func.h"
24#include "tilehighlight_func.h"
25#include "window_gui.h"
26#include "vehiclelist.h"
27#include "vehicle_func.h"
28#include "order_backup.h"
29#include "zoom_func.h"
30#include "error.h"
31#include "depot_cmd.h"
32#include "train_cmd.h"
33#include "vehicle_cmd.h"
34#include "core/geometry_func.hpp"
35
36#include "widgets/depot_widget.h"
37
38#include "table/strings.h"
39
40#include "safeguards.h"
41
42/*
43 * Since all depot window sizes aren't the same, we need to modify sizes a little.
44 * It's done with the following arrays of widget indexes. Each of them tells if a widget side should be moved and in what direction.
45 * How long they should be moved and for what window types are controlled in ShowDepotWindow()
46 */
47
49 static constexpr NWidgetPart _nested_train_depot_widgets[] = {
50 NWidget(NWID_HORIZONTAL),
51 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
52 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_D_SHOW_RENAME), SetAspect(WidgetDimensions::ASPECT_RENAME), // rename button
53 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_D_RENAME), SetAspect(WidgetDimensions::ASPECT_RENAME), SetDataTip(SPR_RENAME, STR_DEPOT_RENAME_TOOLTIP),
54 EndContainer(),
55 NWidget(WWT_CAPTION, COLOUR_GREY, WID_D_CAPTION), SetDataTip(STR_DEPOT_CAPTION, STR_NULL),
56 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_D_LOCATION), SetAspect(WidgetDimensions::ASPECT_LOCATION), SetDataTip(SPR_GOTO_LOCATION, STR_NULL),
57 NWidget(WWT_SHADEBOX, COLOUR_GREY),
58 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
59 NWidget(WWT_STICKYBOX, COLOUR_GREY),
60 EndContainer(),
61 NWidget(NWID_HORIZONTAL),
62 NWidget(NWID_VERTICAL),
63 NWidget(WWT_MATRIX, COLOUR_GREY, WID_D_MATRIX), SetResize(1, 1), SetScrollbar(WID_D_V_SCROLL),
64 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_D_SHOW_H_SCROLL),
65 NWidget(NWID_HSCROLLBAR, COLOUR_GREY, WID_D_H_SCROLL),
66 EndContainer(),
67 EndContainer(),
68 NWidget(NWID_VERTICAL),
69 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_D_SELL), SetDataTip(0x0, STR_NULL), SetResize(0, 1), SetFill(0, 1),
70 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_D_SHOW_SELL_CHAIN),
71 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_D_SELL_CHAIN), SetDataTip(SPR_SELL_CHAIN_TRAIN, STR_DEPOT_DRAG_WHOLE_TRAIN_TO_SELL_TOOLTIP), SetResize(0, 1), SetFill(0, 1),
72 EndContainer(),
73 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_D_SELL_ALL), SetDataTip(0x0, STR_NULL),
74 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_D_AUTOREPLACE), SetDataTip(0x0, STR_NULL),
75 EndContainer(),
76 NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_D_V_SCROLL),
77 EndContainer(),
78 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
79 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_D_BUILD), SetDataTip(0x0, STR_NULL), SetFill(1, 1), SetResize(1, 0),
80 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_D_CLONE), SetDataTip(0x0, STR_NULL), SetFill(1, 1), SetResize(1, 0),
81 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_D_VEHICLE_LIST), SetDataTip(0x0, STR_NULL), SetAspect(WidgetDimensions::ASPECT_VEHICLE_ICON), SetFill(0, 1),
82 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_D_STOP_ALL), SetDataTip(SPR_FLAG_VEH_STOPPED, STR_NULL), SetAspect(WidgetDimensions::ASPECT_VEHICLE_FLAG), SetFill(0, 1),
83 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_D_START_ALL), SetDataTip(SPR_FLAG_VEH_RUNNING, STR_NULL), SetAspect(WidgetDimensions::ASPECT_VEHICLE_FLAG), SetFill(0, 1),
84 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
85 EndContainer(),
86};
87
88static WindowDesc _train_depot_desc(
89 WDP_AUTO, "depot_train", 362, 123,
90 WC_VEHICLE_DEPOT, WC_NONE,
91 0,
92 _nested_train_depot_widgets
93);
94
95static WindowDesc _road_depot_desc(
96 WDP_AUTO, "depot_roadveh", 316, 97,
97 WC_VEHICLE_DEPOT, WC_NONE,
98 0,
99 _nested_train_depot_widgets
100);
101
102static WindowDesc _ship_depot_desc(
103 WDP_AUTO, "depot_ship", 306, 99,
104 WC_VEHICLE_DEPOT, WC_NONE,
105 0,
106 _nested_train_depot_widgets
107);
108
109static WindowDesc _aircraft_depot_desc(
110 WDP_AUTO, "depot_aircraft", 332, 99,
111 WC_VEHICLE_DEPOT, WC_NONE,
112 0,
113 _nested_train_depot_widgets
114);
115
116extern void DepotSortList(VehicleList *list);
117
123 void CcCloneVehicle(Commands, const CommandCost &result, VehicleID veh_id)
124{
125 if (result.Failed()) return;
126
127 const Vehicle *v = Vehicle::Get(veh_id);
128
129 ShowVehicleViewWindow(v);
130}
131
132static void TrainDepotMoveVehicle(const Vehicle *wagon, VehicleID sel, const Vehicle *head)
133{
134 const Vehicle *v = Vehicle::Get(sel);
135
136 if (v == wagon) return;
137
138 if (wagon == nullptr) {
139 if (head != nullptr) wagon = head->Last();
140 } else {
141 wagon = wagon->Previous();
142 if (wagon == nullptr) return;
143 }
144
145 if (wagon == v) return;
146
147 Command<CMD_MOVE_RAIL_VEHICLE>::Post(STR_ERROR_CAN_T_MOVE_VEHICLE, v->tile, v->index, wagon == nullptr ? INVALID_VEHICLE : wagon->index, _ctrl_pressed);
148}
149
150 static VehicleCellSize _base_block_sizes_depot[VEH_COMPANY_END];
151 static VehicleCellSize _base_block_sizes_purchase[VEH_COMPANY_END];
152 static uint _consistent_train_width;
153
161 VehicleCellSize GetVehicleImageCellSize(VehicleType type, EngineImageType image_type)
162{
163 switch (image_type) {
164 case EIT_IN_DEPOT: return _base_block_sizes_depot[type];
165 case EIT_PURCHASE: return _base_block_sizes_purchase[type];
166 default: NOT_REACHED();
167 }
168}
169
170static void InitBlocksizeForVehicles(VehicleType type, EngineImageType image_type)
171{
172 int max_extend_left = 0;
173 int max_extend_right = 0;
174 uint max_height = 0;
175
176 for (const Engine *e : Engine::IterateType(type)) {
177 if (!e->IsEnabled()) continue;
178
179 EngineID eid = e->index;
180 uint x, y;
181 int x_offs, y_offs;
182
183 switch (type) {
184 default: NOT_REACHED();
185 case VEH_TRAIN: GetTrainSpriteSize( eid, x, y, x_offs, y_offs, image_type); break;
186 case VEH_ROAD: GetRoadVehSpriteSize( eid, x, y, x_offs, y_offs, image_type); break;
187 case VEH_SHIP: GetShipSpriteSize( eid, x, y, x_offs, y_offs, image_type); break;
188 case VEH_AIRCRAFT: GetAircraftSpriteSize(eid, x, y, x_offs, y_offs, image_type); break;
189 }
190 if (y > max_height) max_height = y;
191 if (-x_offs > max_extend_left) max_extend_left = -x_offs;
192 if ((int)x + x_offs > max_extend_right) max_extend_right = x + x_offs;
193 }
194
195 int min_extend = ScaleSpriteTrad(16);
196 int max_extend = ScaleSpriteTrad(98);
197
198 switch (image_type) {
199 case EIT_IN_DEPOT:
200 _base_block_sizes_depot[type].height = std::max<uint>(ScaleSpriteTrad(GetVehicleHeight(type)), max_height);
201 _base_block_sizes_depot[type].extend_left = Clamp(max_extend_left, min_extend, max_extend);
202 _base_block_sizes_depot[type].extend_right = Clamp(max_extend_right, min_extend, max_extend);
203 break;
204 case EIT_PURCHASE:
205 _base_block_sizes_purchase[type].height = std::max<uint>(ScaleSpriteTrad(GetVehicleHeight(type)), max_height);
206 _base_block_sizes_purchase[type].extend_left = Clamp(max_extend_left, min_extend, max_extend);
207 _base_block_sizes_purchase[type].extend_right = Clamp(max_extend_right, min_extend, max_extend);
208 break;
209
210 default: NOT_REACHED();
211 }
212}
213
218 void InitDepotWindowBlockSizes()
219{
220 for (VehicleType vt = VEH_BEGIN; vt < VEH_COMPANY_END; vt++) {
221 InitBlocksizeForVehicles(vt, EIT_IN_DEPOT);
222 InitBlocksizeForVehicles(vt, EIT_PURCHASE);
223 }
224
225 _consistent_train_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
226 bool first = true;
227 for (const Engine *e : Engine::IterateType(VEH_TRAIN)) {
228 if (!e->IsEnabled()) continue;
229
230 uint w = TRAININFO_DEFAULT_VEHICLE_WIDTH;
231 if (e->GetGRF() != nullptr && is_custom_sprite(e->u.rail.image_index)) {
232 w = e->GetGRF()->traininfo_vehicle_width;
233 if (w != VEHICLEINFO_FULL_VEHICLE_WIDTH) {
234 /* Hopeless.
235 * This is a NewGRF vehicle that uses TRAININFO_DEFAULT_VEHICLE_WIDTH.
236 * If the vehicles are shorter than 8/8 we have fractional lengths, which are not consistent after rounding.
237 */
238 _consistent_train_width = 0;
239 break;
240 }
241 }
242
243 if (first) {
244 _consistent_train_width = w;
245 first = false;
246 } else if (w != _consistent_train_width) {
247 _consistent_train_width = 0;
248 break;
249 }
250 }
251}
252
253static void DepotSellAllConfirmationCallback(Window *w, bool confirmed);
254const Sprite *GetAircraftSprite(EngineID engine);
255
256 struct DepotWindow : Window {
257 VehicleID sel;
258 VehicleID vehicle_over;
259 VehicleType type;
260 bool generate_list;
261 bool check_unitnumber_digits;
262 WidgetID hovered_widget;
263 VehicleList vehicle_list;
264 VehicleList wagon_list;
265 uint unitnumber_digits;
266 uint num_columns;
267 Scrollbar *hscroll;
268 Scrollbar *vscroll;
269
270 DepotWindow(WindowDesc &desc, TileIndex tile, VehicleType type) : Window(desc)
271 {
272 assert(IsCompanyBuildableVehicleType(type)); // ensure that we make the call with a valid type
273
274 this->sel = INVALID_VEHICLE;
275 this->vehicle_over = INVALID_VEHICLE;
276 this->generate_list = true;
277 this->check_unitnumber_digits = true;
278 this->hovered_widget = -1;
279 this->type = type;
280 this->num_columns = 1; // for non-trains this gets set in FinishInitNested()
281 this->unitnumber_digits = 2;
282
283 this->CreateNestedTree();
284 this->hscroll = (this->type == VEH_TRAIN ? this->GetScrollbar(WID_D_H_SCROLL) : nullptr);
285 this->vscroll = this->GetScrollbar(WID_D_V_SCROLL);
286 /* Don't show 'rename button' of aircraft hangar */
287 this->GetWidget<NWidgetStacked>(WID_D_SHOW_RENAME)->SetDisplayedPlane(type == VEH_AIRCRAFT ? SZSP_NONE : 0);
288 /* Only train depots have a horizontal scrollbar and a 'sell chain' button */
289 if (type == VEH_TRAIN) this->GetWidget<NWidgetCore>(WID_D_MATRIX)->widget_data = 1 << MAT_COL_START;
290 this->GetWidget<NWidgetStacked>(WID_D_SHOW_H_SCROLL)->SetDisplayedPlane(type == VEH_TRAIN ? 0 : SZSP_HORIZONTAL);
291 this->GetWidget<NWidgetStacked>(WID_D_SHOW_SELL_CHAIN)->SetDisplayedPlane(type == VEH_TRAIN ? 0 : SZSP_NONE);
292 this->SetupWidgetData(type);
293 this->FinishInitNested(tile);
294
295 this->owner = GetTileOwner(tile);
296 OrderBackup::Reset();
297 }
298
299 void Close([[maybe_unused]] int data = 0) override
300 {
301 CloseWindowById(WC_BUILD_VEHICLE, this->window_number);
302 CloseWindowById(GetWindowClassForVehicleType(this->type), VehicleListIdentifier(VL_DEPOT_LIST, this->type, this->owner, this->GetDepotIndex()).Pack(), false);
303 OrderBackup::Reset(this->window_number);
304 this->Window::Close();
305 }
306
312 void DrawVehicleInDepot(const Vehicle *v, const Rect &r) const
313 {
314 bool free_wagon = false;
315
316 bool rtl = _current_text_dir == TD_RTL;
317 Rect text = r.Shrink(RectPadding::zero, WidgetDimensions::scaled.matrix); /* Ract for text elements, horizontal is already applied. */
318 Rect image = r.Indent(this->header_width, rtl).Indent(this->count_width, !rtl); /* Rect for vehicle images */
319
320 switch (v->type) {
321 case VEH_TRAIN: {
322 const Train *u = Train::From(v);
323 free_wagon = u->IsFreeWagon();
324
325 uint x_space = free_wagon ?
326 ScaleSpriteTrad(_consistent_train_width != 0 ? _consistent_train_width : TRAININFO_DEFAULT_VEHICLE_WIDTH) :
327 0;
328
329 DrawTrainImage(u, image.Indent(x_space, rtl), this->sel, EIT_IN_DEPOT, free_wagon ? 0 : this->hscroll->GetPosition(), this->vehicle_over);
330
331 /* Length of consist in tiles with 1 fractional digit (rounded up) */
332 SetDParam(0, CeilDiv(u->gcache.cached_total_length * 10, TILE_SIZE));
333 SetDParam(1, 1);
334 Rect count = text.WithWidth(this->count_width - WidgetDimensions::scaled.hsep_normal, !rtl);
335 DrawString(count.left, count.right, count.bottom - GetCharacterHeight(FS_SMALL) + 1, STR_JUST_DECIMAL, TC_BLACK, SA_RIGHT, false, FS_SMALL); // Draw the counter
336 break;
337 }
338
339 case VEH_ROAD: DrawRoadVehImage( v, image, this->sel, EIT_IN_DEPOT); break;
340 case VEH_SHIP: DrawShipImage( v, image, this->sel, EIT_IN_DEPOT); break;
341 case VEH_AIRCRAFT: DrawAircraftImage(v, image, this->sel, EIT_IN_DEPOT); break;
342 default: NOT_REACHED();
343 }
344
345 uint diff_x, diff_y;
346 if (v->IsGroundVehicle()) {
347 /* Arrange unitnumber and flag horizontally */
348 diff_x = this->flag_size.width + WidgetDimensions::scaled.hsep_normal;
349 diff_y = WidgetDimensions::scaled.matrix.top;
350 } else {
351 /* Arrange unitnumber and flag vertically */
352 diff_x = 0;
353 diff_y = WidgetDimensions::scaled.matrix.top + GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal;
354 }
355
356 text = text.WithWidth(this->header_width - WidgetDimensions::scaled.hsep_normal, rtl).WithHeight(GetCharacterHeight(FS_NORMAL)).Indent(diff_x, rtl);
357 if (free_wagon) {
358 DrawString(text, STR_DEPOT_NO_ENGINE);
359 } else {
360 Rect flag = r.WithWidth(this->flag_size.width, rtl).WithHeight(this->flag_size.height).Translate(0, diff_y);
361 DrawSpriteIgnorePadding((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, flag, SA_CENTER);
362
363 SetDParam(0, v->unitnumber);
364 DrawString(text, STR_JUST_COMMA, (v->max_age - CalendarTime::DAYS_IN_LEAP_YEAR) >= v->age ? TC_BLACK : TC_RED);
365 }
366 }
367
368 void DrawWidget(const Rect &r, WidgetID widget) const override
369 {
370 if (widget != WID_D_MATRIX) return;
371
372 bool rtl = _current_text_dir == TD_RTL;
373
374 /* Set the row and number of boxes in each row based on the number of boxes drawn in the matrix */
375 const NWidgetCore *wid = this->GetWidget<NWidgetCore>(WID_D_MATRIX);
376
377 /* Set up rect for each cell */
378 Rect ir = r.WithHeight(this->resize.step_height);
379 if (this->num_columns != 1) ir = ir.WithWidth(this->resize.step_width, rtl);
380 ir = ir.Shrink(WidgetDimensions::scaled.framerect, RectPadding::zero);
381
382 /* Draw vertical separators at whole tiles.
383 * This only works in two cases:
384 * - All vehicles use VEHICLEINFO_FULL_VEHICLE_WIDTH as reference width.
385 * - All vehicles are 8/8. This cannot be checked for NewGRF, so instead we check for "all vehicles are original vehicles".
386 */
387 if (this->type == VEH_TRAIN && _consistent_train_width != 0) {
388 int w = ScaleSpriteTrad(2 * _consistent_train_width);
389 int col = GetColourGradient(wid->colour, SHADE_NORMAL);
390 Rect image = ir.Indent(this->header_width, rtl).Indent(this->count_width, !rtl);
391 int first_line = w + (-this->hscroll->GetPosition()) % w;
392 if (rtl) {
393 for (int x = image.right - first_line; x >= image.left; x -= w) {
394 GfxDrawLine(x, r.top, x, r.bottom, col, ScaleGUITrad(1), ScaleGUITrad(3));
395 }
396 } else {
397 for (int x = image.left + first_line; x <= image.right; x += w) {
398 GfxDrawLine(x, r.top, x, r.bottom, col, ScaleGUITrad(1), ScaleGUITrad(3));
399 }
400 }
401 }
402
403 uint16_t rows_in_display = wid->current_y / wid->resize_y;
404
405 uint num = this->vscroll->GetPosition() * this->num_columns;
406 uint maxval = static_cast<uint>(std::min<size_t>(this->vehicle_list.size(), num + (rows_in_display * this->num_columns)));
407 for (; num < maxval; ir = ir.Translate(0, this->resize.step_height)) { // Draw the rows
408 Rect cell = ir; /* Keep track of horizontal cells */
409 for (uint i = 0; i < this->num_columns && num < maxval; i++, num++) {
410 /* Draw all vehicles in the current row */
411 const Vehicle *v = this->vehicle_list[num];
412 this->DrawVehicleInDepot(v, cell);
413 cell = cell.Translate(rtl ? -(int)this->resize.step_width : (int)this->resize.step_width, 0);
414 }
415 }
416
417 maxval = static_cast<uint>(std::min<size_t>(this->vehicle_list.size() + this->wagon_list.size(), (this->vscroll->GetPosition() * this->num_columns) + (rows_in_display * this->num_columns)));
418
419 /* Draw the train wagons without an engine in front. */
420 for (; num < maxval; num++, ir = ir.Translate(0, this->resize.step_height)) {
421 const Vehicle *v = this->wagon_list[num - this->vehicle_list.size()];
422 this->DrawVehicleInDepot(v, ir);
423 }
424 }
425
426 void SetStringParameters(WidgetID widget) const override
427 {
428 if (widget != WID_D_CAPTION) return;
429
430 SetDParam(0, this->type);
431 SetDParam(1, this->GetDepotIndex());
432 }
433
434 struct GetDepotVehiclePtData {
435 const Vehicle *head;
436 const Vehicle *wagon;
437 };
438
439 enum DepotGUIAction {
440 MODE_ERROR,
441 MODE_DRAG_VEHICLE,
442 MODE_SHOW_VEHICLE,
443 MODE_START_STOP,
444 };
445
446 DepotGUIAction GetVehicleFromDepotWndPt(int x, int y, const Vehicle **veh, GetDepotVehiclePtData *d)
447 {
448 this->RefreshVehicleList();
449
450 const NWidgetCore *matrix_widget = this->GetWidget<NWidgetCore>(WID_D_MATRIX);
451 /* Make X relative to widget. Y is left alone for GetScrolledRowFromWidget(). */
452 x -= matrix_widget->pos_x;
453 /* In case of RTL the widgets are swapped as a whole */
454 if (_current_text_dir == TD_RTL) x = matrix_widget->current_x - x;
455
456 uint xt = 0, xm = 0, ym = 0;
457 if (this->type == VEH_TRAIN) {
458 xm = x;
459 } else {
460 xt = x / this->resize.step_width;
461 xm = x % this->resize.step_width;
462 if (xt >= this->num_columns) return MODE_ERROR;
463 }
464 ym = (y - matrix_widget->pos_y) % this->resize.step_height;
465
466 int32_t row = this->vscroll->GetScrolledRowFromWidget(y, this, WID_D_MATRIX);
467 uint pos = (row * this->num_columns) + xt;
468
469 if (row == INT32_MAX || this->vehicle_list.size() + this->wagon_list.size() <= pos) {
470 /* Clicking on 'line' / 'block' without a vehicle */
471 if (this->type == VEH_TRAIN) {
472 /* End the dragging */
473 d->head = nullptr;
474 d->wagon = nullptr;
475 return MODE_DRAG_VEHICLE;
476 } else {
477 return MODE_ERROR; // empty block, so no vehicle is selected
478 }
479 }
480
481 bool wagon = false;
482 if (this->vehicle_list.size() > pos) {
483 *veh = this->vehicle_list[pos];
484 /* Skip vehicles that are scrolled off the list */
485 if (this->type == VEH_TRAIN) x += this->hscroll->GetPosition();
486 } else {
487 pos -= (uint)this->vehicle_list.size();
488 *veh = this->wagon_list[pos];
489 /* free wagons don't have an initial loco. */
490 x -= ScaleSpriteTrad(VEHICLEINFO_FULL_VEHICLE_WIDTH);
491 wagon = true;
492 }
493
494 const Train *v = nullptr;
495 if (this->type == VEH_TRAIN) {
496 v = Train::From(*veh);
497 d->head = d->wagon = v;
498 }
499
500 if (xm <= this->header_width) {
501 switch (this->type) {
502 case VEH_TRAIN:
503 if (wagon) return MODE_ERROR;
504 [[fallthrough]];
505
506 case VEH_ROAD:
507 if (xm <= this->flag_size.width) return MODE_START_STOP;
508 break;
509
510 case VEH_SHIP:
511 case VEH_AIRCRAFT:
512 if (xm <= this->flag_size.width && ym >= (uint)(GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal)) return MODE_START_STOP;
513 break;
514
515 default: NOT_REACHED();
516 }
517 return MODE_SHOW_VEHICLE;
518 }
519
520 if (this->type != VEH_TRAIN) return MODE_DRAG_VEHICLE;
521
522 /* Clicking on the counter */
523 if (xm >= matrix_widget->current_x - this->count_width) return wagon ? MODE_ERROR : MODE_SHOW_VEHICLE;
524
525 /* Account for the header */
526 x -= this->header_width;
527
528 /* find the vehicle in this row that was clicked */
529 for (; v != nullptr; v = v->Next()) {
530 x -= v->GetDisplayImageWidth();
531 if (x < 0) break;
532 }
533
534 d->wagon = (v != nullptr ? v->GetFirstEnginePart() : nullptr);
535
536 return MODE_DRAG_VEHICLE;
537 }
538
544 void DepotClick(int x, int y)
545 {
546 GetDepotVehiclePtData gdvp = { nullptr, nullptr };
547 const Vehicle *v = nullptr;
548 DepotGUIAction mode = this->GetVehicleFromDepotWndPt(x, y, &v, &gdvp);
549
550 if (this->type == VEH_TRAIN) v = gdvp.wagon;
551
552 switch (mode) {
553 case MODE_ERROR: // invalid
554 return;
555
556 case MODE_DRAG_VEHICLE: { // start dragging of vehicle
557 if (v != nullptr && VehicleClicked(v)) return;
558
559 VehicleID sel = this->sel;
560
561 if (this->type == VEH_TRAIN && sel != INVALID_VEHICLE) {
562 this->sel = INVALID_VEHICLE;
563 TrainDepotMoveVehicle(v, sel, gdvp.head);
564 } else if (v != nullptr) {
565 SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
566 SetMouseCursorVehicle(v, EIT_IN_DEPOT);
567 _cursor.vehchain = _ctrl_pressed;
568
569 this->sel = v->index;
570 this->SetDirty();
571 }
572 break;
573 }
574
575 case MODE_SHOW_VEHICLE: // show info window
576 ShowVehicleViewWindow(v);
577 break;
578
579 case MODE_START_STOP: // click start/stop flag
580 StartStopVehicle(v, false);
581 break;
582
583 default: NOT_REACHED();
584 }
585 }
586
593 void SetupWidgetData(VehicleType type)
594 {
595 this->GetWidget<NWidgetCore>(WID_D_STOP_ALL)->tool_tip = STR_DEPOT_MASS_STOP_DEPOT_TRAIN_TOOLTIP + type;
596 this->GetWidget<NWidgetCore>(WID_D_START_ALL)->tool_tip = STR_DEPOT_MASS_START_DEPOT_TRAIN_TOOLTIP + type;
597 this->GetWidget<NWidgetCore>(WID_D_SELL)->tool_tip = STR_DEPOT_TRAIN_SELL_TOOLTIP + type;
598 this->GetWidget<NWidgetCore>(WID_D_SELL_ALL)->tool_tip = STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TOOLTIP + type;
599
600 this->GetWidget<NWidgetCore>(WID_D_BUILD)->SetDataTip(STR_DEPOT_TRAIN_NEW_VEHICLES_BUTTON + type, STR_DEPOT_TRAIN_NEW_VEHICLES_TOOLTIP + type);
601 this->GetWidget<NWidgetCore>(WID_D_CLONE)->SetDataTip(STR_DEPOT_CLONE_TRAIN + type, STR_DEPOT_CLONE_TRAIN_DEPOT_INFO + type);
602
603 this->GetWidget<NWidgetCore>(WID_D_LOCATION)->tool_tip = STR_DEPOT_TRAIN_LOCATION_TOOLTIP + type;
604 this->GetWidget<NWidgetCore>(WID_D_VEHICLE_LIST)->tool_tip = STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TOOLTIP + type;
605 this->GetWidget<NWidgetCore>(WID_D_AUTOREPLACE)->tool_tip = STR_DEPOT_AUTOREPLACE_TRAIN_TOOLTIP + type;
606 this->GetWidget<NWidgetCore>(WID_D_MATRIX)->tool_tip = STR_DEPOT_TRAIN_LIST_TOOLTIP + this->type;
607
608 switch (type) {
609 default: NOT_REACHED();
610
611 case VEH_TRAIN:
612 this->GetWidget<NWidgetCore>(WID_D_VEHICLE_LIST)->widget_data = STR_TRAIN;
613
614 /* Sprites */
615 this->GetWidget<NWidgetCore>(WID_D_SELL)->widget_data = SPR_SELL_TRAIN;
616 this->GetWidget<NWidgetCore>(WID_D_SELL_ALL)->widget_data = SPR_SELL_ALL_TRAIN;
617 this->GetWidget<NWidgetCore>(WID_D_AUTOREPLACE)->widget_data = SPR_REPLACE_TRAIN;
618 break;
619
620 case VEH_ROAD:
621 this->GetWidget<NWidgetCore>(WID_D_VEHICLE_LIST)->widget_data = STR_LORRY;
622
623 /* Sprites */
624 this->GetWidget<NWidgetCore>(WID_D_SELL)->widget_data = SPR_SELL_ROADVEH;
625 this->GetWidget<NWidgetCore>(WID_D_SELL_ALL)->widget_data = SPR_SELL_ALL_ROADVEH;
626 this->GetWidget<NWidgetCore>(WID_D_AUTOREPLACE)->widget_data = SPR_REPLACE_ROADVEH;
627 break;
628
629 case VEH_SHIP:
630 this->GetWidget<NWidgetCore>(WID_D_VEHICLE_LIST)->widget_data = STR_SHIP;
631
632 /* Sprites */
633 this->GetWidget<NWidgetCore>(WID_D_SELL)->widget_data = SPR_SELL_SHIP;
634 this->GetWidget<NWidgetCore>(WID_D_SELL_ALL)->widget_data = SPR_SELL_ALL_SHIP;
635 this->GetWidget<NWidgetCore>(WID_D_AUTOREPLACE)->widget_data = SPR_REPLACE_SHIP;
636 break;
637
638 case VEH_AIRCRAFT:
639 this->GetWidget<NWidgetCore>(WID_D_VEHICLE_LIST)->widget_data = STR_PLANE;
640
641 /* Sprites */
642 this->GetWidget<NWidgetCore>(WID_D_SELL)->widget_data = SPR_SELL_AIRCRAFT;
643 this->GetWidget<NWidgetCore>(WID_D_SELL_ALL)->widget_data = SPR_SELL_ALL_AIRCRAFT;
644 this->GetWidget<NWidgetCore>(WID_D_AUTOREPLACE)->widget_data = SPR_REPLACE_AIRCRAFT;
645 break;
646 }
647 }
648
649 uint count_width;
650 uint header_width;
651 Dimension flag_size;
652 VehicleCellSize cell_size;
653
654 void OnInit() override
655 {
656 this->cell_size = GetVehicleImageCellSize(this->type, EIT_IN_DEPOT);
657 this->flag_size = maxdim(GetScaledSpriteSize(SPR_FLAG_VEH_STOPPED), GetScaledSpriteSize(SPR_FLAG_VEH_RUNNING));
658 }
659
660 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
661 {
662 switch (widget) {
663 case WID_D_MATRIX: {
664 uint min_height = 0;
665
666 if (this->type == VEH_TRAIN) {
667 SetDParamMaxValue(0, 1000, 0, FS_SMALL);
668 SetDParam(1, 1);
669 this->count_width = GetStringBoundingBox(STR_JUST_DECIMAL, FS_SMALL).width + WidgetDimensions::scaled.hsep_normal;
670 } else {
671 this->count_width = 0;
672 }
673
674 SetDParamMaxDigits(0, this->unitnumber_digits);
675 Dimension unumber = GetStringBoundingBox(STR_JUST_COMMA);
676
677 if (this->type == VEH_TRAIN || this->type == VEH_ROAD) {
678 min_height = std::max<uint>(unumber.height, this->flag_size.height);
679 this->header_width = unumber.width + WidgetDimensions::scaled.hsep_normal + this->flag_size.width + WidgetDimensions::scaled.hsep_normal;
680 } else {
681 min_height = unumber.height + WidgetDimensions::scaled.vsep_normal + this->flag_size.height;
682 this->header_width = std::max<uint>(unumber.width, this->flag_size.width) + WidgetDimensions::scaled.hsep_normal;
683 }
684 int base_width = this->count_width + this->header_width + padding.width;
685
686 resize.height = std::max<uint>(this->cell_size.height, min_height + padding.height);
687 if (this->type == VEH_TRAIN) {
688 resize.width = 1;
689 size.width = base_width + 2 * ScaleSpriteTrad(29); // about 2 parts
690 size.height = resize.height * 6;
691 } else {
692 resize.width = base_width + this->cell_size.extend_left + this->cell_size.extend_right;
693 size.width = resize.width * (this->type == VEH_ROAD ? 5 : 3);
694 size.height = resize.height * (this->type == VEH_ROAD ? 5 : 3);
695 }
696 fill.width = resize.width;
697 fill.height = resize.height;
698 break;
699 }
700 }
701 }
702
708 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
709 {
710 this->generate_list = true;
711 }
712
713 void RefreshVehicleList()
714 {
715 if (this->generate_list) {
716 /* Generate the vehicle list
717 * It's ok to use the wagon pointers for non-trains as they will be ignored */
718 BuildDepotVehicleList(this->type, this->window_number, &this->vehicle_list, &this->wagon_list);
719 this->generate_list = false;
720 DepotSortList(&this->vehicle_list);
721
722 this->check_unitnumber_digits = true;
723 }
724 }
725
726 void OnPaint() override
727 {
728 this->RefreshVehicleList();
729
730 if (this->check_unitnumber_digits) {
731 this->check_unitnumber_digits = false;
732 uint new_unitnumber_digits = GetUnitNumberDigits(this->vehicle_list);
733 /* Only increase the size; do not decrease to prevent constant changes */
734 if (this->unitnumber_digits < new_unitnumber_digits) {
735 this->unitnumber_digits = new_unitnumber_digits;
736 this->ReInit();
737 }
738 }
739
740 /* determine amount of items for scroller */
741 if (this->type == VEH_TRAIN) {
742 uint max_width = ScaleSpriteTrad(VEHICLEINFO_FULL_VEHICLE_WIDTH);
743 for (uint num = 0; num < this->vehicle_list.size(); num++) {
744 uint width = 0;
745 for (const Train *v = Train::From(this->vehicle_list[num]); v != nullptr; v = v->Next()) {
746 width += v->GetDisplayImageWidth();
747 }
748 max_width = std::max(max_width, width);
749 }
750 /* Always have 1 empty row, so people can change the setting of the train */
751 this->vscroll->SetCount(this->vehicle_list.size() + this->wagon_list.size() + 1);
752 /* Always make it longer than the longest train, so you can attach vehicles at the end, and also see the next vertical tile separator line */
753 this->hscroll->SetCount(max_width + ScaleSpriteTrad(2 * VEHICLEINFO_FULL_VEHICLE_WIDTH + 1));
754 } else {
755 this->vscroll->SetCount(CeilDiv((uint)this->vehicle_list.size(), this->num_columns));
756 }
757
758 /* Setup disabled buttons. */
759 TileIndex tile = this->window_number;
760 this->SetWidgetsDisabledState(!IsTileOwner(tile, _local_company),
761 WID_D_STOP_ALL,
762 WID_D_START_ALL,
763 WID_D_SELL,
764 WID_D_SELL_CHAIN,
765 WID_D_SELL_ALL,
766 WID_D_BUILD,
767 WID_D_CLONE,
768 WID_D_RENAME,
769 WID_D_AUTOREPLACE);
770
771 this->DrawWidgets();
772 }
773
774 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
775 {
776 switch (widget) {
777 case WID_D_MATRIX: // List
778 this->DepotClick(pt.x, pt.y);
779 break;
780
781 case WID_D_BUILD: // Build vehicle
782 ResetObjectToPlace();
783 ShowBuildVehicleWindow(this->window_number, this->type);
784 break;
785
786 case WID_D_CLONE: // Clone button
787 this->SetWidgetDirty(WID_D_CLONE);
788 this->ToggleWidgetLoweredState(WID_D_CLONE);
789
790 if (this->IsWidgetLowered(WID_D_CLONE)) {
791 static const CursorID clone_icons[] = {
792 SPR_CURSOR_CLONE_TRAIN, SPR_CURSOR_CLONE_ROADVEH,
793 SPR_CURSOR_CLONE_SHIP, SPR_CURSOR_CLONE_AIRPLANE
794 };
795
796 SetObjectToPlaceWnd(clone_icons[this->type], PAL_NONE, HT_VEHICLE, this);
797 } else {
798 ResetObjectToPlace();
799 }
800 break;
801
802 case WID_D_LOCATION:
803 if (_ctrl_pressed) {
804 ShowExtraViewportWindow(this->window_number);
805 } else {
806 ScrollMainWindowToTile(this->window_number);
807 }
808 break;
809
810 case WID_D_RENAME: // Rename button
811 SetDParam(0, this->type);
812 SetDParam(1, Depot::GetByTile((TileIndex)this->window_number)->index);
813 ShowQueryString(STR_DEPOT_NAME, STR_DEPOT_RENAME_DEPOT_CAPTION, MAX_LENGTH_DEPOT_NAME_CHARS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS);
814 break;
815
816 case WID_D_STOP_ALL:
817 case WID_D_START_ALL: {
818 VehicleListIdentifier vli(VL_DEPOT_LIST, this->type, this->owner);
819 Command<CMD_MASS_START_STOP>::Post(this->window_number, widget == WID_D_START_ALL, false, vli);
820 break;
821 }
822
823 case WID_D_SELL_ALL:
824 /* Only open the confirmation window if there are anything to sell */
825 if (!this->vehicle_list.empty() || !this->wagon_list.empty()) {
826 SetDParam(0, this->type);
827 SetDParam(1, this->GetDepotIndex());
828 ShowQuery(
829 STR_DEPOT_CAPTION,
830 STR_DEPOT_SELL_CONFIRMATION_TEXT,
831 this,
832 DepotSellAllConfirmationCallback
833 );
834 }
835 break;
836
837 case WID_D_VEHICLE_LIST:
838 ShowVehicleListWindow(GetTileOwner(this->window_number), this->type, (TileIndex)this->window_number);
839 break;
840
841 case WID_D_AUTOREPLACE:
842 Command<CMD_DEPOT_MASS_AUTOREPLACE>::Post(this->window_number, this->type);
843 break;
844
845 }
846 }
847
848 void OnQueryTextFinished(std::optional<std::string> str) override
849 {
850 if (!str.has_value()) return;
851
852 /* Do depot renaming */
853 Command<CMD_RENAME_DEPOT>::Post(STR_ERROR_CAN_T_RENAME_DEPOT, this->GetDepotIndex(), *str);
854 }
855
856 bool OnRightClick([[maybe_unused]] Point pt, WidgetID widget) override
857 {
858 if (widget != WID_D_MATRIX) return false;
859
860 GetDepotVehiclePtData gdvp = { nullptr, nullptr };
861 const Vehicle *v = nullptr;
862 DepotGUIAction mode = this->GetVehicleFromDepotWndPt(pt.x, pt.y, &v, &gdvp);
863
864 if (this->type == VEH_TRAIN) v = gdvp.wagon;
865
866 if (v == nullptr || mode != MODE_DRAG_VEHICLE) return false;
867
868 CargoArray capacity{}, loaded{};
869
870 /* Display info for single (articulated) vehicle, or for whole chain starting with selected vehicle */
871 bool whole_chain = (this->type == VEH_TRAIN && _ctrl_pressed);
872
873 /* loop through vehicle chain and collect cargoes */
874 uint num = 0;
875 for (const Vehicle *w = v; w != nullptr; w = w->Next()) {
876 if (w->cargo_cap > 0 && w->cargo_type < NUM_CARGO) {
877 capacity[w->cargo_type] += w->cargo_cap;
878 loaded [w->cargo_type] += w->cargo.StoredCount();
879 }
880
881 if (w->type == VEH_TRAIN && !w->HasArticulatedPart()) {
882 num++;
883 if (!whole_chain) break;
884 }
885 }
886
887 /* Build tooltipstring */
888 static std::string details;
889 details.clear();
890
891 for (const CargoSpec *cs : _sorted_cargo_specs) {
892 CargoID cargo_type = cs->Index();
893 if (capacity[cargo_type] == 0) continue;
894
895 SetDParam(0, cargo_type); // {CARGO} #1
896 SetDParam(1, loaded[cargo_type]); // {CARGO} #2
897 SetDParam(2, cargo_type); // {SHORTCARGO} #1
898 SetDParam(3, capacity[cargo_type]); // {SHORTCARGO} #2
899 AppendStringInPlace(details, STR_DEPOT_VEHICLE_TOOLTIP_CARGO);
900 }
901
902 /* Show tooltip window */
903 SetDParam(0, whole_chain ? num : v->engine_type);
904 SetDParamStr(1, details);
905 GuiShowTooltips(this, whole_chain ? STR_DEPOT_VEHICLE_TOOLTIP_CHAIN : STR_DEPOT_VEHICLE_TOOLTIP, TCC_RIGHT_CLICK, 2);
906
907 return true;
908 }
909
915 bool OnVehicleSelect(const Vehicle *v) override
916 {
917 if (_ctrl_pressed) {
918 /* Share-clone, do not open new viewport, and keep tool active */
919 Command<CMD_CLONE_VEHICLE>::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, this->window_number, v->index, true);
920 } else {
921 /* Copy-clone, open viewport for new vehicle, and deselect the tool (assume player wants to change things on new vehicle) */
922 if (Command<CMD_CLONE_VEHICLE>::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, CcCloneVehicle, this->window_number, v->index, false)) {
923 ResetObjectToPlace();
924 }
925 }
926
927 return true;
928 }
929
936 bool OnVehicleSelect(VehicleList::const_iterator begin, VehicleList::const_iterator end) override
937 {
938 if (!_ctrl_pressed) {
939 /* If CTRL is not pressed: If all the vehicles in this list have the same orders, then copy orders */
940 if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
941 return VehiclesHaveSameEngineList(v1, v2);
942 })) {
943 if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
944 return VehiclesHaveSameOrderList(v1, v2);
945 })) {
946 OnVehicleSelect(*begin);
947 } else {
948 ShowErrorMessage(STR_ERROR_CAN_T_BUY_TRAIN + (*begin)->type, STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST, WL_INFO);
949 }
950 } else {
951 ShowErrorMessage(STR_ERROR_CAN_T_BUY_TRAIN + (*begin)->type, STR_ERROR_CAN_T_CLONE_VEHICLE_LIST, WL_INFO);
952 }
953 } else {
954 /* If CTRL is pressed: If all the vehicles in this list share orders, then copy orders */
955 if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
956 return VehiclesHaveSameEngineList(v1, v2);
957 })) {
958 if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
959 return v1->FirstShared() == v2->FirstShared();
960 })) {
961 OnVehicleSelect(*begin);
962 } else {
963 ShowErrorMessage(STR_ERROR_CAN_T_BUY_TRAIN + (*begin)->type, STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST, WL_INFO);
964 }
965 } else {
966 ShowErrorMessage(STR_ERROR_CAN_T_BUY_TRAIN + (*begin)->type, STR_ERROR_CAN_T_CLONE_VEHICLE_LIST, WL_INFO);
967 }
968 }
969
970 return true;
971 }
972
973 void OnPlaceObjectAbort() override
974 {
975 /* abort clone */
976 this->RaiseWidget(WID_D_CLONE);
977 this->SetWidgetDirty(WID_D_CLONE);
978
979 /* abort drag & drop */
980 this->sel = INVALID_VEHICLE;
981 this->vehicle_over = INVALID_VEHICLE;
982 this->SetWidgetDirty(WID_D_MATRIX);
983
984 if (this->hovered_widget != -1) {
985 this->SetWidgetLoweredState(this->hovered_widget, false);
986 this->SetWidgetDirty(this->hovered_widget);
987 this->hovered_widget = -1;
988 }
989 }
990
991 bool last_overlay_state;
992 void OnMouseLoop() override
993 {
994 if (last_overlay_state != ShowCargoIconOverlay()) {
995 last_overlay_state = ShowCargoIconOverlay();
996 this->SetDirty();
997 }
998 }
999
1000 void OnMouseDrag(Point pt, WidgetID widget) override
1001 {
1002 if (this->sel == INVALID_VEHICLE) return;
1003 if (widget != this->hovered_widget) {
1004 if (this->hovered_widget == WID_D_SELL || this->hovered_widget == WID_D_SELL_CHAIN) {
1005 this->SetWidgetLoweredState(this->hovered_widget, false);
1006 this->SetWidgetDirty(this->hovered_widget);
1007 }
1008 this->hovered_widget = widget;
1009 if (this->hovered_widget == WID_D_SELL || this->hovered_widget == WID_D_SELL_CHAIN) {
1010 this->SetWidgetLoweredState(this->hovered_widget, true);
1011 this->SetWidgetDirty(this->hovered_widget);
1012 }
1013 }
1014 if (this->type != VEH_TRAIN) return;
1015
1016 /* A rail vehicle is dragged.. */
1017 if (widget != WID_D_MATRIX) { // ..outside of the depot matrix.
1018 if (this->vehicle_over != INVALID_VEHICLE) {
1019 this->vehicle_over = INVALID_VEHICLE;
1020 this->SetWidgetDirty(WID_D_MATRIX);
1021 }
1022 return;
1023 }
1024
1025 const Vehicle *v = nullptr;
1026 GetDepotVehiclePtData gdvp = {nullptr, nullptr};
1027
1028 if (this->GetVehicleFromDepotWndPt(pt.x, pt.y, &v, &gdvp) != MODE_DRAG_VEHICLE) return;
1029
1030 VehicleID new_vehicle_over = INVALID_VEHICLE;
1031 if (gdvp.head != nullptr) {
1032 if (gdvp.wagon == nullptr && gdvp.head->Last()->index != this->sel) { // ..at the end of the train.
1033 /* NOTE: As a wagon can't be moved at the begin of a train, head index isn't used to mark a drag-and-drop
1034 * destination inside a train. This head index is then used to indicate that a wagon is inserted at
1035 * the end of the train.
1036 */
1037 new_vehicle_over = gdvp.head->index;
1038 } else if (gdvp.wagon != nullptr && gdvp.head != gdvp.wagon &&
1039 gdvp.wagon->index != this->sel &&
1040 gdvp.wagon->Previous()->index != this->sel) { // ..over an existing wagon.
1041 new_vehicle_over = gdvp.wagon->index;
1042 }
1043 }
1044
1045 if (this->vehicle_over == new_vehicle_over) return;
1046
1047 this->vehicle_over = new_vehicle_over;
1048 this->SetWidgetDirty(widget);
1049 }
1050
1051 void OnDragDrop(Point pt, WidgetID widget) override
1052 {
1053 switch (widget) {
1054 case WID_D_MATRIX: {
1055 const Vehicle *v = nullptr;
1056 VehicleID sel = this->sel;
1057
1058 this->sel = INVALID_VEHICLE;
1059 this->SetDirty();
1060
1061 if (this->type == VEH_TRAIN) {
1062 GetDepotVehiclePtData gdvp = { nullptr, nullptr };
1063
1064 if (this->GetVehicleFromDepotWndPt(pt.x, pt.y, &v, &gdvp) == MODE_DRAG_VEHICLE && sel != INVALID_VEHICLE) {
1065 if (gdvp.wagon != nullptr && gdvp.wagon->index == sel && _ctrl_pressed) {
1066 Command<CMD_REVERSE_TRAIN_DIRECTION>::Post(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE, Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true);
1067 } else if (gdvp.wagon == nullptr || gdvp.wagon->index != sel) {
1068 this->vehicle_over = INVALID_VEHICLE;
1069 TrainDepotMoveVehicle(gdvp.wagon, sel, gdvp.head);
1070 } else if (gdvp.head != nullptr && gdvp.head->IsFrontEngine()) {
1071 ShowVehicleViewWindow(gdvp.head);
1072 }
1073 }
1074 } else if (this->GetVehicleFromDepotWndPt(pt.x, pt.y, &v, nullptr) == MODE_DRAG_VEHICLE && v != nullptr && sel == v->index) {
1075 ShowVehicleViewWindow(v);
1076 }
1077 break;
1078 }
1079
1080 case WID_D_SELL: case WID_D_SELL_CHAIN: {
1081 if (this->IsWidgetDisabled(widget)) return;
1082 if (this->sel == INVALID_VEHICLE) return;
1083
1084 this->HandleButtonClick(widget);
1085
1086 const Vehicle *v = Vehicle::Get(this->sel);
1087 this->sel = INVALID_VEHICLE;
1088 this->SetDirty();
1089
1090 bool sell_cmd = (v->type == VEH_TRAIN && (widget == WID_D_SELL_CHAIN || _ctrl_pressed));
1091 Command<CMD_SELL_VEHICLE>::Post(GetCmdSellVehMsg(v->type), v->tile, v->index, sell_cmd, true, INVALID_CLIENT_ID);
1092 break;
1093 }
1094
1095 default:
1096 this->sel = INVALID_VEHICLE;
1097 this->SetDirty();
1098 break;
1099 }
1100 this->hovered_widget = -1;
1101 _cursor.vehchain = false;
1102 }
1103
1104 void OnTimeout() override
1105 {
1106 if (!this->IsWidgetDisabled(WID_D_SELL)) {
1107 this->RaiseWidget(WID_D_SELL);
1108 this->SetWidgetDirty(WID_D_SELL);
1109 }
1110 if (this->GetWidget<NWidgetBase>(WID_D_SELL) != nullptr && !this->IsWidgetDisabled(WID_D_SELL_CHAIN)) {
1111 this->RaiseWidget(WID_D_SELL_CHAIN);
1112 this->SetWidgetDirty(WID_D_SELL_CHAIN);
1113 }
1114 }
1115
1116 void OnResize() override
1117 {
1118 this->vscroll->SetCapacityFromWidget(this, WID_D_MATRIX);
1119 NWidgetCore *nwi = this->GetWidget<NWidgetCore>(WID_D_MATRIX);
1120 if (this->type == VEH_TRAIN) {
1121 this->hscroll->SetCapacity(nwi->current_x - this->header_width - this->count_width);
1122 } else {
1123 this->num_columns = nwi->current_x / nwi->resize_x;
1124 }
1125 }
1126
1127 EventState OnCTRLStateChange() override
1128 {
1129 if (this->sel != INVALID_VEHICLE) {
1130 _cursor.vehchain = _ctrl_pressed;
1131 this->SetWidgetDirty(WID_D_MATRIX);
1132 return ES_HANDLED;
1133 }
1134
1135 return ES_NOT_HANDLED;
1136 }
1137
1143 inline uint16_t GetDepotIndex() const
1144 {
1145 return (this->type == VEH_AIRCRAFT) ? ::GetStationIndex(this->window_number) : ::GetDepotIndex(this->window_number);
1146 }
1147};
1148
1149static void DepotSellAllConfirmationCallback(Window *win, bool confirmed)
1150{
1151 if (confirmed) {
1152 DepotWindow *w = (DepotWindow*)win;
1153 TileIndex tile = w->window_number;
1154 VehicleType vehtype = w->type;
1155 Command<CMD_DEPOT_SELL_ALL_VEHICLES>::Post(tile, vehtype);
1156 }
1157}
1158
1164 void ShowDepotWindow(TileIndex tile, VehicleType type)
1165{
1166 if (BringWindowToFrontById(WC_VEHICLE_DEPOT, tile) != nullptr) return;
1167
1168 switch (type) {
1169 default: NOT_REACHED();
1170 case VEH_TRAIN: new DepotWindow(_train_depot_desc, tile, type); break;
1171 case VEH_ROAD: new DepotWindow(_road_depot_desc, tile, type); break;
1172 case VEH_SHIP: new DepotWindow(_ship_depot_desc, tile, type); break;
1173 case VEH_AIRCRAFT: new DepotWindow(_aircraft_depot_desc, tile, type); break;
1174 }
1175}
1176
1181 void DeleteDepotHighlightOfVehicle(const Vehicle *v)
1182{
1183 DepotWindow *w;
1184
1185 /* If we haven't got any vehicles on the mouse pointer, we haven't got any highlighted in any depots either
1186 * If that is the case, we can skip looping though the windows and save time
1187 */
1188 if (_special_mouse_mode != WSM_DRAGDROP) return;
1189
1190 w = dynamic_cast<DepotWindow*>(FindWindowById(WC_VEHICLE_DEPOT, v->tile));
1191 if (w != nullptr) {
1192 if (w->sel == v->index) ResetObjectToPlace();
1193 }
1194}
aircraft.h
Base for aircraft.
GetAircraftSpriteSize
void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type)
Get the size of the sprite of an aircraft sprite heading west (used for lists).
Definition aircraft_cmd.cpp:249
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
CargoID
uint8_t CargoID
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:22
NUM_CARGO
static const CargoID NUM_CARGO
Maximum number of cargo types in a game.
Definition cargo_type.h:74
_sorted_cargo_specs
std::vector< const CargoSpec * > _sorted_cargo_specs
Cargo specifications sorted alphabetically by name.
Definition cargotype.cpp:192
CommandCost
Common return value for all commands.
Definition command_type.h:23
CommandCost::Failed
bool Failed() const
Did this command fail?
Definition command_type.h:171
NWidgetCore
Base class for a 'real' widget.
Definition widget_type.h:371
Scrollbar
Scrollbar data structure.
Definition widget_type.h:694
Scrollbar::SetCount
void SetCount(size_t num)
Sets the number of elements in the list.
Definition widget_type.h:780
Scrollbar::SetCapacity
void SetCapacity(size_t capacity)
Set the capacity of visible elements.
Definition widget_type.h:794
Scrollbar::GetScrolledRowFromWidget
size_type GetScrolledRowFromWidget(int clickpos, const Window *const w, WidgetID widget, int padding=0, int line_height=-1) const
Compute the row of a scrolled widget that a user clicked in.
Definition widget.cpp:2377
Scrollbar::SetCapacityFromWidget
void SetCapacityFromWidget(Window *w, WidgetID widget, int padding=0)
Set capacity of visible elements from the size and resize properties of a widget.
Definition widget.cpp:2451
Scrollbar::GetPosition
size_type GetPosition() const
Gets the position of the first visible element in the list.
Definition widget_type.h:740
TimerGameConst< struct Calendar >::DAYS_IN_LEAP_YEAR
static constexpr int DAYS_IN_LEAP_YEAR
sometimes, you need one day more...
Definition timer_game_common.h:150
WidgetDimensions::scaled
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:28
WidgetDimensions::vsep_normal
int vsep_normal
Normal vertical spacing.
Definition window_gui.h:60
WidgetDimensions::matrix
RectPadding matrix
Padding of WWT_MATRIX items.
Definition window_gui.h:44
WidgetDimensions::hsep_normal
int hsep_normal
Normal horizontal spacing.
Definition window_gui.h:63
command_func.h
Functions related to commands.
Commands
Commands
List of commands.
Definition command_type.h:187
_local_company
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition company_cmd.cpp:52
company_func.h
Functions related to companies.
depot_base.h
Base for all depots (except hangars)
depot_cmd.h
Command definitions related to depots.
InitDepotWindowBlockSizes
void InitDepotWindowBlockSizes()
Set the size of the blocks in the window so we can be sure that they are big enough for the vehicle s...
Definition depot_gui.cpp:218
_nested_train_depot_widgets
static constexpr NWidgetPart _nested_train_depot_widgets[]
Nested widget definition for train depots.
Definition depot_gui.cpp:49
_consistent_train_width
static uint _consistent_train_width
Whether trains of all lengths are consistently scaled. Either TRAININFO_DEFAULT_VEHICLE_WIDTH,...
Definition depot_gui.cpp:152
DeleteDepotHighlightOfVehicle
void DeleteDepotHighlightOfVehicle(const Vehicle *v)
Removes the highlight of a vehicle in a depot window.
Definition depot_gui.cpp:1181
_base_block_sizes_depot
static VehicleCellSize _base_block_sizes_depot[VEH_COMPANY_END]
Cell size for vehicle images in the depot view.
Definition depot_gui.cpp:150
ShowDepotWindow
void ShowDepotWindow(TileIndex tile, VehicleType type)
Opens a depot window.
Definition depot_gui.cpp:1164
GetVehicleImageCellSize
VehicleCellSize GetVehicleImageCellSize(VehicleType type, EngineImageType image_type)
Get the GUI cell size for a vehicle image.
Definition depot_gui.cpp:161
CcCloneVehicle
void CcCloneVehicle(Commands, const CommandCost &result, VehicleID veh_id)
This is the Callback method after the cloning attempt of a vehicle.
Definition depot_gui.cpp:123
_base_block_sizes_purchase
static VehicleCellSize _base_block_sizes_purchase[VEH_COMPANY_END]
Cell size for vehicle images in the purchase list.
Definition depot_gui.cpp:151
MAX_LENGTH_DEPOT_NAME_CHARS
static const uint MAX_LENGTH_DEPOT_NAME_CHARS
The maximum length of a depot name in characters including '\0'.
Definition depot_type.h:18
depot_widget.h
Types related to the depot widgets.
WID_D_LOCATION
@ WID_D_LOCATION
Location button.
Definition depot_widget.h:27
WID_D_AUTOREPLACE
@ WID_D_AUTOREPLACE
Autoreplace button.
Definition depot_widget.h:20
WID_D_RENAME
@ WID_D_RENAME
Rename button.
Definition depot_widget.h:29
WID_D_SELL_CHAIN
@ WID_D_SELL_CHAIN
Sell chain button.
Definition depot_widget.h:18
WID_D_CLONE
@ WID_D_CLONE
Clone button.
Definition depot_widget.h:26
WID_D_SHOW_SELL_CHAIN
@ WID_D_SHOW_SELL_CHAIN
Show sell chain panel.
Definition depot_widget.h:17
WID_D_SELL
@ WID_D_SELL
Sell button.
Definition depot_widget.h:16
WID_D_H_SCROLL
@ WID_D_H_SCROLL
Horizontal scrollbar.
Definition depot_widget.h:24
WID_D_SHOW_H_SCROLL
@ WID_D_SHOW_H_SCROLL
Show horizontal scrollbar panel.
Definition depot_widget.h:23
WID_D_MATRIX
@ WID_D_MATRIX
Matrix of vehicles.
Definition depot_widget.h:21
WID_D_V_SCROLL
@ WID_D_V_SCROLL
Vertical scrollbar.
Definition depot_widget.h:22
WID_D_SELL_ALL
@ WID_D_SELL_ALL
Sell all button.
Definition depot_widget.h:19
WID_D_VEHICLE_LIST
@ WID_D_VEHICLE_LIST
List of vehicles.
Definition depot_widget.h:30
WID_D_START_ALL
@ WID_D_START_ALL
Start all button.
Definition depot_widget.h:32
WID_D_SHOW_RENAME
@ WID_D_SHOW_RENAME
Show rename panel.
Definition depot_widget.h:28
WID_D_BUILD
@ WID_D_BUILD
Build button.
Definition depot_widget.h:25
WID_D_CAPTION
@ WID_D_CAPTION
Caption of window.
Definition depot_widget.h:15
WID_D_STOP_ALL
@ WID_D_STOP_ALL
Stop all button.
Definition depot_widget.h:31
EngineID
uint16_t EngineID
Unique identification number of an engine.
Definition engine_type.h:21
error.h
Functions related to errors.
ShowErrorMessage
void ShowErrorMessage(StringID summary_msg, int x, int y, CommandCost cc)
Display an error message in a window.
Definition error_gui.cpp:367
WL_INFO
@ WL_INFO
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
Definition error.h:24
GetCharacterHeight
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:77
maxdim
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Definition geometry_func.cpp:22
geometry_func.hpp
Geometry functions.
GetStringBoundingBox
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:851
DrawString
int DrawString(int left, int right, int top, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition gfx.cpp:657
_ctrl_pressed
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:38
GetScaledSpriteSize
Dimension GetScaledSpriteSize(SpriteID sprid)
Scale sprite size for GUI.
Definition widget.cpp:54
SA_RIGHT
@ SA_RIGHT
Right align the text (must be a single bit).
Definition gfx_type.h:345
SA_CENTER
@ SA_CENTER
Center both horizontally and vertically.
Definition gfx_type.h:353
CursorID
uint32_t CursorID
The number of the cursor (sprite)
Definition gfx_type.h:20
FS_SMALL
@ FS_SMALL
Index of the small font in the font tables.
Definition gfx_type.h:210
FS_NORMAL
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:209
SetFill
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
Definition widget_type.h:1181
SetScrollbar
constexpr NWidgetPart SetScrollbar(WidgetID index)
Attach a scrollbar to a widget.
Definition widget_type.h:1295
SetDataTip
constexpr NWidgetPart SetDataTip(uint32_t data, StringID tip)
Widget part function for setting the data and tooltip.
Definition widget_type.h:1202
NWidget
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=-1)
Widget part function for starting a new 'real' widget.
Definition widget_type.h:1320
EndContainer
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
Definition widget_type.h:1191
SetAspect
constexpr NWidgetPart SetAspect(float ratio, AspectFlags flags=AspectFlags::ResizeX)
Widget part function for setting the aspect ratio.
Definition widget_type.h:1306
SetResize
constexpr NWidgetPart SetResize(int16_t dx, int16_t dy)
Widget part function for setting the resize step.
Definition widget_type.h:1126
Window::SetDirty
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition window.cpp:940
gui.h
GUI functions that shouldn't be here.
ShowExtraViewportWindow
void ShowExtraViewportWindow(TileIndex tile=INVALID_TILE)
Show a new Extra Viewport window.
Definition viewport_gui.cpp:156
CeilDiv
constexpr uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
Definition math_func.hpp:320
Clamp
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
GuiShowTooltips
void GuiShowTooltips(Window *parent, StringID str, TooltipCloseCondition close_tooltip, uint paramcount)
Shows a tooltip.
Definition misc_gui.cpp:740
ShowQuery
void ShowQuery(StringID caption, StringID message, Window *parent, QueryCallbackProc *callback, bool focus)
Show a confirmation window with standard 'yes' and 'no' buttons The window is aligned to the centre o...
Definition misc_gui.cpp:1203
ShowQueryString
void ShowQueryString(StringID str, StringID caption, uint maxsize, Window *parent, CharSetFilter afilter, QueryStringFlags flags)
Show a query popup window with a textbox in it.
Definition misc_gui.cpp:1059
INVALID_CLIENT_ID
@ INVALID_CLIENT_ID
Client is not part of anything.
Definition network_type.h:50
order_backup.h
Functions related to order backups.
GetColourGradient
uint8_t GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
Definition palette.cpp:314
roadveh.h
Road vehicle states.
GetRoadVehSpriteSize
void GetRoadVehSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type)
Get the size of the sprite of a road vehicle sprite heading west (used for lists).
Definition roadveh_cmd.cpp:171
DrawRoadVehImage
void DrawRoadVehImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type, int skip)
Draws an image of a road vehicle chain.
Definition roadveh_gui.cpp:123
safeguards.h
A number of safeguards to prevent using unsafe methods.
ship.h
Base for ships.
GetShipSpriteSize
void GetShipSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type)
Get the size of the sprite of a ship sprite heading west (used for lists).
Definition ship_cmd.cpp:120
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
spritecache.h
Functions to cache sprites in memory.
SPR_CURSOR_MOUSE
static const CursorID SPR_CURSOR_MOUSE
Cursor sprite numbers.
Definition sprites.h:1390
GetStationIndex
StationID GetStationIndex(Tile t)
Get StationID from a tile.
Definition station_map.h:28
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
CS_ALPHANUMERAL
@ CS_ALPHANUMERAL
Both numeric and alphabetic and spaces and stuff.
Definition string_type.h:25
SetDParamMaxValue
void SetDParamMaxValue(size_t n, uint64_t max_value, uint min_count, FontSize size)
Set DParam n to some number that is suitable for string size computations.
Definition strings.cpp:127
AppendStringInPlace
void AppendStringInPlace(std::string &result, StringID string)
Resolve the given StringID and append in place into an existing std::string with all the associated D...
Definition strings.cpp:345
SetDParam
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
Definition strings.cpp:104
_current_text_dir
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:56
SetDParamStr
void SetDParamStr(size_t n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition strings.cpp:371
SetDParamMaxDigits
void SetDParamMaxDigits(size_t n, uint count, FontSize size)
Set DParam n to some number that is suitable for string size computations.
Definition strings.cpp:143
strings_func.h
Functions related to OTTD's strings.
TD_RTL
@ TD_RTL
Text is written right-to-left by default.
Definition strings_type.h:24
BaseVehicle::type
VehicleType type
Type of vehicle.
Definition vehicle_type.h:51
CargoArray
Class for storing amounts of cargo.
Definition cargo_type.h:114
CargoSpec
Specification of a cargo type.
Definition cargotype.h:76
CommandHelper
Definition command_func.h:83
CursorVars::vehchain
bool vehchain
vehicle chain is dragged
Definition gfx_type.h:150
DepotWindow::GetDepotVehiclePtData
Definition depot_gui.cpp:434
DepotWindow
Definition depot_gui.cpp:256
DepotWindow::header_width
uint header_width
Width of unit number and flag, including separator.
Definition depot_gui.cpp:650
DepotWindow::OnMouseLoop
void OnMouseLoop() override
Called for every mouse loop run, which is at least once per (game) tick.
Definition depot_gui.cpp:992
DepotWindow::vehicle_over
VehicleID vehicle_over
Rail vehicle over which another one is dragged, INVALID_VEHICLE if none.
Definition depot_gui.cpp:258
DepotWindow::OnDragDrop
void OnDragDrop(Point pt, WidgetID widget) override
A dragged 'object' has been released.
Definition depot_gui.cpp:1051
DepotWindow::SetStringParameters
void SetStringParameters(WidgetID widget) const override
Initialize string parameters for a widget.
Definition depot_gui.cpp:426
DepotWindow::count_width
uint count_width
Width of length count, including separator.
Definition depot_gui.cpp:649
DepotWindow::OnQueryTextFinished
void OnQueryTextFinished(std::optional< std::string > str) override
The query window opened from this window has closed.
Definition depot_gui.cpp:848
DepotWindow::OnTimeout
void OnTimeout() override
Called when this window's timeout has been reached.
Definition depot_gui.cpp:1104
DepotWindow::Close
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
Definition depot_gui.cpp:299
DepotWindow::num_columns
uint num_columns
Number of columns.
Definition depot_gui.cpp:266
DepotWindow::GetDepotIndex
uint16_t GetDepotIndex() const
Gets the DepotID of the current window.
Definition depot_gui.cpp:1143
DepotWindow::OnCTRLStateChange
EventState OnCTRLStateChange() override
The state of the control key has changed.
Definition depot_gui.cpp:1127
DepotWindow::OnClick
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition depot_gui.cpp:774
DepotWindow::SetupWidgetData
void SetupWidgetData(VehicleType type)
Function to set up vehicle specific widgets (mainly sprites and strings).
Definition depot_gui.cpp:593
DepotWindow::OnPlaceObjectAbort
void OnPlaceObjectAbort() override
The user cancelled a tile highlight mode that has been set.
Definition depot_gui.cpp:973
DepotWindow::OnRightClick
bool OnRightClick(Point pt, WidgetID widget) override
A click with the right mouse button has been made on the window.
Definition depot_gui.cpp:856
DepotWindow::OnMouseDrag
void OnMouseDrag(Point pt, WidgetID widget) override
An 'object' is being dragged at the provided position, highlight the target if possible.
Definition depot_gui.cpp:1000
DepotWindow::OnVehicleSelect
bool OnVehicleSelect(const Vehicle *v) override
Clones a vehicle.
Definition depot_gui.cpp:915
DepotWindow::flag_size
Dimension flag_size
Size of start/stop flag.
Definition depot_gui.cpp:651
DepotWindow::DepotClick
void DepotClick(int x, int y)
Handle click in the depot matrix.
Definition depot_gui.cpp:544
DepotWindow::UpdateWidgetSize
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
Definition depot_gui.cpp:660
DepotWindow::hscroll
Scrollbar * hscroll
Only for trains.
Definition depot_gui.cpp:267
DepotWindow::OnVehicleSelect
bool OnVehicleSelect(VehicleList::const_iterator begin, VehicleList::const_iterator end) override
Clones a vehicle from a vehicle list.
Definition depot_gui.cpp:936
DepotWindow::OnResize
void OnResize() override
Called after the window got resized.
Definition depot_gui.cpp:1116
DepotWindow::OnPaint
void OnPaint() override
The window must be repainted.
Definition depot_gui.cpp:726
DepotWindow::hovered_widget
WidgetID hovered_widget
Index of the widget being hovered during drag/drop. -1 if no drag is in progress.
Definition depot_gui.cpp:262
DepotWindow::OnInit
void OnInit() override
Notification that the nested widget tree gets initialized.
Definition depot_gui.cpp:654
DepotWindow::DrawVehicleInDepot
void DrawVehicleInDepot(const Vehicle *v, const Rect &r) const
Draw a vehicle in the depot window in the box with the top left corner at x,y.
Definition depot_gui.cpp:312
DepotWindow::DrawWidget
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition depot_gui.cpp:368
DepotWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition depot_gui.cpp:708
DepotWindow::cell_size
VehicleCellSize cell_size
Vehicle sprite cell size.
Definition depot_gui.cpp:652
Dimension
Dimensions (a width and height) of a rectangle in 2D.
Definition geometry_type.hpp:30
Engine
Definition engine_base.h:37
Engine::IterateType
static Pool::IterateWrapperFiltered< Engine, EngineTypeFilter > IterateType(VehicleType vt, size_t from=0)
Returns an iterable ensemble of all valid engines of the given type.
Definition engine_base.h:190
GroundVehicleCache::cached_total_length
uint16_t cached_total_length
Length of the whole vehicle (valid only for the first engine).
Definition ground_vehicle.hpp:43
GroundVehicle::gcache
GroundVehicleCache gcache
Cache of often calculated values.
Definition ground_vehicle.hpp:83
GroundVehicle::IsFreeWagon
bool IsFreeWagon() const
Check if the vehicle is a free wagon (got no engine in front of it).
Definition ground_vehicle.hpp:312
NWidgetPart
Partial widget specification to allow NWidgets to be written nested.
Definition widget_type.h:1075
OrderBackup::Reset
static void Reset(TileIndex tile=INVALID_TILE, bool from_gui=true)
Reset the OrderBackups from GUI/game logic.
Definition order_backup.cpp:187
Point
Coordinates of a point in 2D.
Definition geometry_type.hpp:21
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition pool_type.hpp:238
Pool::PoolItem<&_vehicle_pool >::Get
static Titem * Get(size_t index)
Returns Titem with given index.
Definition pool_type.hpp:339
Rect
Specification of a rectangle with absolute coordinates of all edges.
Definition geometry_type.hpp:75
Rect::WithWidth
Rect WithWidth(int width, bool end) const
Copy Rect and set its width.
Definition geometry_type.hpp:185
Rect::Shrink
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
Definition geometry_type.hpp:98
Rect::WithHeight
Rect WithHeight(int height, bool end=false) const
Copy Rect and set its height.
Definition geometry_type.hpp:211
Rect::Indent
Rect Indent(int indent, bool end) const
Copy Rect and indent it from its position.
Definition geometry_type.hpp:198
Rect::Translate
Rect Translate(int x, int y) const
Copy and translate Rect by x,y pixels.
Definition geometry_type.hpp:174
ResizeInfo::step_height
uint step_height
Step-size of height resize changes.
Definition window_gui.h:214
ResizeInfo::step_width
uint step_width
Step-size of width resize changes.
Definition window_gui.h:213
SpecializedVehicle::Next
T * Next() const
Get next vehicle in the chain.
Definition vehicle_base.h:1130
SpecializedVehicle::From
static T * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
Definition vehicle_base.h:1215
SpecializedVehicle::GetFirstEnginePart
T * GetFirstEnginePart()
Get the first part of an articulated engine.
Definition vehicle_base.h:1156
Sprite
Data structure describing a sprite.
Definition spritecache.h:17
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
Train
'Train' is either a loco or a wagon.
Definition train.h:89
Train::GetDisplayImageWidth
int GetDisplayImageWidth(Point *offset=nullptr) const
Get the width of a train vehicle image in the GUI.
Definition train_cmd.cpp:460
VehicleCellSize
Dimensions of a cell in the purchase/depot windows.
Definition vehicle_gui.h:83
VehicleCellSize::extend_left
uint extend_left
Extend of the cell to the left.
Definition vehicle_gui.h:85
VehicleCellSize::height
uint height
Vehicle cell height.
Definition vehicle_gui.h:84
VehicleCellSize::extend_right
uint extend_right
Extend of the cell to the right.
Definition vehicle_gui.h:86
VehicleListIdentifier
The information about a vehicle list.
Definition vehiclelist.h:28
Vehicle
Vehicle data structure.
Definition vehicle_base.h:244
Vehicle::engine_type
EngineID engine_type
The type of engine used for this vehicle.
Definition vehicle_base.h:323
Vehicle::Last
Vehicle * Last()
Get the last vehicle of this vehicle chain.
Definition vehicle_base.h:651
Vehicle::Next
Vehicle * Next() const
Get the next vehicle of this vehicle.
Definition vehicle_base.h:632
Vehicle::vehstatus
uint8_t vehstatus
Status.
Definition vehicle_base.h:354
Vehicle::age
TimerGameCalendar::Date age
Age in calendar days.
Definition vehicle_base.h:292
Vehicle::max_age
TimerGameCalendar::Date max_age
Maximum age.
Definition vehicle_base.h:294
Vehicle::IsGroundVehicle
debug_inline bool IsGroundVehicle() const
Check if the vehicle is a ground vehicle.
Definition vehicle_base.h:515
Vehicle::Previous
Vehicle * Previous() const
Get the previous vehicle of this vehicle.
Definition vehicle_base.h:639
Vehicle::tile
TileIndex tile
Current tile index.
Definition vehicle_base.h:264
Vehicle::unitnumber
UnitID unitnumber
unit number, for display purposes only
Definition vehicle_base.h:326
WindowDesc
High level window description.
Definition window_gui.h:159
Window
Data structure for an opened window.
Definition window_gui.h:273
Window::ReInit
void ReInit(int rx=0, int ry=0, bool reposition=false)
Re-initialize a window, and optionally change its size.
Definition window.cpp:952
Window::Close
virtual void Close(int data=0)
Hide the window and all its child windows, and mark them for a later deletion.
Definition window.cpp:1047
Window::FinishInitNested
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1733
Window::DrawWidgets
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:732
Window::RaiseWidget
void RaiseWidget(WidgetID widget_index)
Marks a widget as raised.
Definition window_gui.h:475
Window::SetWidgetDirty
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:551
Window::resize
ResizeInfo resize
Resize information.
Definition window_gui.h:314
Window::SetWidgetsDisabledState
void SetWidgetsDisabledState(bool disab_stat, Args... widgets)
Sets the enabled/disabled status of a list of widgets.
Definition window_gui.h:521
Window::CreateNestedTree
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1723
Window::IsWidgetLowered
bool IsWidgetLowered(WidgetID widget_index) const
Gets the lowered state of a widget.
Definition window_gui.h:497
Window::IsWidgetDisabled
bool IsWidgetDisabled(WidgetID widget_index) const
Gets the enabled/disabled status of a widget.
Definition window_gui.h:416
Window::owner
Owner owner
The owner of the content shown in this window. Company colour is acquired from this variable.
Definition window_gui.h:316
Window::SetWidgetLoweredState
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition window_gui.h:447
Window::GetWidget
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:977
Window::HandleButtonClick
void HandleButtonClick(WidgetID widget)
Do all things to make a button look clicked and mark it to be unclicked in a few ticks.
Definition window.cpp:590
Window::GetScrollbar
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition window.cpp:314
Window::width
int width
width of the window (number of pixels to the right in x direction)
Definition window_gui.h:311
Window::ToggleWidgetLoweredState
void ToggleWidgetLoweredState(WidgetID widget_index)
Invert the lowered/raised status of a widget.
Definition window_gui.h:456
Window::window_number
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:302
textbuf_gui.h
Stuff related to the text buffer GUI.
QSF_ENABLE_DEFAULT
@ QSF_ENABLE_DEFAULT
enable the 'Default' button ("\0" is returned)
Definition textbuf_gui.h:21
QSF_LEN_IN_CHARS
@ QSF_LEN_IN_CHARS
the length of the string is counted in characters
Definition textbuf_gui.h:22
IsTileOwner
bool IsTileOwner(Tile tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition tile_map.h:214
GetTileOwner
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
Definition tile_map.h:178
TILE_SIZE
static const uint TILE_SIZE
Tile size in world coordinates.
Definition tile_type.h:15
tilehighlight_func.h
Functions related to tile highlights.
ResetObjectToPlace
void ResetObjectToPlace()
Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows).
Definition viewport.cpp:3498
SetObjectToPlaceWnd
void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Window *w)
Change the cursor and mouse click/drag handling to a mode for performing special operations like tile...
Definition viewport.cpp:3435
HT_DRAG
@ HT_DRAG
dragging items in the depot windows
Definition tilehighlight_type.h:24
HT_VEHICLE
@ HT_VEHICLE
vehicle is accepted as target as well (bitmask)
Definition tilehighlight_type.h:27
train.h
Base for the train class.
GetTrainSpriteSize
void GetTrainSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type)
Get the size of the sprite of a train sprite heading west, or both heads (used for lists).
Definition train_cmd.cpp:581
train_cmd.h
Command definitions related to trains.
DrawTrainImage
void DrawTrainImage(const Train *v, const Rect &r, VehicleID selection, EngineImageType image_type, int skip, VehicleID drag_dest)
Draws an image of a whole train.
Definition train_gui.cpp:93
VehiclesHaveSameEngineList
bool VehiclesHaveSameEngineList(const Vehicle *v1, const Vehicle *v2)
Checks if two vehicle chains have the same list of engines.
Definition vehicle.cpp:3272
VehiclesHaveSameOrderList
bool VehiclesHaveSameOrderList(const Vehicle *v1, const Vehicle *v2)
Checks if two vehicles have the same list of orders.
Definition vehicle.cpp:3289
VS_STOPPED
@ VS_STOPPED
Vehicle is stopped by the player.
Definition vehicle_base.h:34
vehicle_cmd.h
Command definitions for vehicles.
vehicle_func.h
Functions related to vehicles.
IsCompanyBuildableVehicleType
bool IsCompanyBuildableVehicleType(VehicleType type)
Is the given vehicle type buildable by a company?
Definition vehicle_func.h:91
GetUnitNumberDigits
uint GetUnitNumberDigits(VehicleList &vehicles)
Get the number of digits the biggest unit number of a set of vehicles has.
Definition vehicle_gui.cpp:208
ShowVehicleViewWindow
void ShowVehicleViewWindow(const Vehicle *v)
Shows the vehicle view window of the given vehicle.
Definition vehicle_gui.cpp:3504
VehicleClicked
bool VehicleClicked(const Vehicle *v)
Dispatch a "vehicle selected" event if any window waits for it.
Definition vehicle_gui.cpp:3514
StartStopVehicle
void StartStopVehicle(const Vehicle *v, bool texteffect)
Executes CMD_START_STOP_VEHICLE for given vehicle.
Definition vehicle_gui.cpp:3003
SetMouseCursorVehicle
void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type)
Set the mouse cursor to look like a vehicle.
Definition vehicle_gui.cpp:3622
ShowCargoIconOverlay
bool ShowCargoIconOverlay()
Test if cargo icon overlays should be drawn.
Definition vehicle_gui.cpp:336
GetVehicleHeight
uint GetVehicleHeight(VehicleType type)
Get the height of a single vehicle in the GUIs.
Definition vehicle_gui.h:74
GetWindowClassForVehicleType
WindowClass GetWindowClassForVehicleType(VehicleType vt)
Get WindowClass for vehicle list of given vehicle type.
Definition vehicle_gui.h:97
EngineImageType
EngineImageType
Visualisation contexts of vehicles and engines.
Definition vehicle_type.h:78
EIT_PURCHASE
@ EIT_PURCHASE
Vehicle drawn in purchase list, autoreplace gui, ...
Definition vehicle_type.h:83
EIT_IN_DEPOT
@ EIT_IN_DEPOT
Vehicle drawn in depot.
Definition vehicle_type.h:80
VehicleType
VehicleType
Available vehicle types.
Definition vehicle_type.h:21
VEH_ROAD
@ VEH_ROAD
Road vehicle type.
Definition vehicle_type.h:25
VEH_AIRCRAFT
@ VEH_AIRCRAFT
Aircraft vehicle type.
Definition vehicle_type.h:27
VEH_SHIP
@ VEH_SHIP
Ship vehicle type.
Definition vehicle_type.h:26
VEH_TRAIN
@ VEH_TRAIN
Train vehicle type.
Definition vehicle_type.h:24
VEH_COMPANY_END
@ VEH_COMPANY_END
Last company-ownable type.
Definition vehicle_type.h:29
VehicleID
uint32_t VehicleID
The type all our vehicle IDs have.
Definition vehicle_type.h:16
INVALID_VEHICLE
static const VehicleID INVALID_VEHICLE
Constant representing a non-existing vehicle.
Definition vehicle_type.h:54
BuildDepotVehicleList
void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engines, VehicleList *wagons, bool individual_wagons)
Generate a list of vehicles inside a depot.
Definition vehiclelist.cpp:104
vehiclelist.h
Functions and type for generating vehicle lists.
VehicleList
std::vector< const Vehicle * > VehicleList
A list of vehicles.
Definition vehiclelist.h:54
ScrollMainWindowToTile
bool ScrollMainWindowToTile(TileIndex tile, bool instant)
Scrolls the viewport of the main window to a given location.
Definition viewport.cpp:2515
viewport_func.h
Functions related to (drawing on) viewports.
ScaleGUITrad
static RectPadding ScaleGUITrad(const RectPadding &r)
Scale a RectPadding to GUI zoom level.
Definition widget.cpp:35
SZSP_HORIZONTAL
@ SZSP_HORIZONTAL
Display plane with zero size vertically, and filling and resizing horizontally.
Definition widget_type.h:483
SZSP_NONE
@ SZSP_NONE
Display plane with zero size in both directions (none filling and resizing).
Definition widget_type.h:484
NC_EQUALSIZE
@ NC_EQUALSIZE
Value of the NCB_EQUALSIZE flag.
Definition widget_type.h:524
WWT_PUSHTXTBTN
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
Definition widget_type.h:113
WWT_IMGBTN
@ WWT_IMGBTN
(Toggle) Button with image
Definition widget_type.h:52
WWT_PUSHIMGBTN
@ WWT_PUSHIMGBTN
Normal push-button (no toggle button) with image caption.
Definition widget_type.h:114
NWID_HORIZONTAL
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:75
WWT_TEXTBTN
@ WWT_TEXTBTN
(Toggle) Button with text
Definition widget_type.h:55
WWT_STICKYBOX
@ WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition widget_type.h:66
WWT_MATRIX
@ WWT_MATRIX
Grid of rows and columns.
Definition widget_type.h:59
WWT_SHADEBOX
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition widget_type.h:64
WWT_CAPTION
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition widget_type.h:61
NWID_VSCROLLBAR
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition widget_type.h:85
NWID_VERTICAL
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:77
WWT_CLOSEBOX
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:69
NWID_HSCROLLBAR
@ NWID_HSCROLLBAR
Horizontal scrollbar.
Definition widget_type.h:84
WWT_RESIZEBOX
@ WWT_RESIZEBOX
Resize box (normally at bottom-right of a window)
Definition widget_type.h:68
WWT_DEFSIZEBOX
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition widget_type.h:65
NWID_SELECTION
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:80
MAT_COL_START
static constexpr uint8_t MAT_COL_START
Bits of the WWT_MATRIX widget data.
Definition widget_type.h:22
CloseWindowById
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition window.cpp:1140
BringWindowToFrontById
Window * BringWindowToFrontById(WindowClass cls, WindowNumber number)
Find a window and make it the relative top-window on the screen.
Definition window.cpp:1223
_special_mouse_mode
SpecialMouseMode _special_mouse_mode
Mode of the mouse.
Definition window.cpp:93
FindWindowById
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition window.cpp:1098
window_gui.h
Functions, definitions and such used only by the GUI.
WSM_DRAGDROP
@ WSM_DRAGDROP
Drag&drop an object.
Definition window_gui.h:1041
AllEqual
bool AllEqual(It begin, It end, Pred pred)
Generic helper function that checks if all elements of the range are equal with respect to the given ...
Definition window_gui.h:940
WDP_AUTO
@ WDP_AUTO
Find a place automatically.
Definition window_gui.h:147
WidgetID
int WidgetID
Widget ID.
Definition window_type.h:18
EventState
EventState
State of handling an event.
Definition window_type.h:743
ES_HANDLED
@ ES_HANDLED
The passed event is handled.
Definition window_type.h:744
ES_NOT_HANDLED
@ ES_NOT_HANDLED
The passed event is not handled.
Definition window_type.h:745
WC_VEHICLE_DEPOT
@ WC_VEHICLE_DEPOT
Depot view; Window numbers:
Definition window_type.h:351
WC_NONE
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:45
WC_BUILD_VEHICLE
@ WC_BUILD_VEHICLE
Build vehicle; Window numbers:
Definition window_type.h:389
zoom_func.h
Functions related to zooming.
ScaleSpriteTrad
int ScaleSpriteTrad(int value)
Scale traditional pixel dimensions to GUI zoom level, for drawing sprites.
Definition zoom_func.h:107