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