OpenTTD Source: src/depot_gui.cpp Source File

OpenTTD Source 15.0-RC2

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