OpenTTD Source 20260512-master-g20b387b91f
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
9
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"
36
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
50static constexpr std::initializer_list<NWidgetPart> _nested_train_depot_widgets = {
53 NWidget(NWID_SELECTION, Colours::Invalid, WID_D_SHOW_RENAME), SetAspect(WidgetDimensions::ASPECT_RENAME), // rename button
54 NWidget(WWT_PUSHIMGBTN, Colours::Grey, WID_D_RENAME), SetAspect(WidgetDimensions::ASPECT_RENAME), SetSpriteTip(SPR_RENAME, STR_DEPOT_RENAME_TOOLTIP),
57 NWidget(WWT_PUSHIMGBTN, Colours::Grey, WID_D_LOCATION), SetAspect(WidgetDimensions::ASPECT_LOCATION), SetSpriteTip(SPR_GOTO_LOCATION),
72 NWidget(WWT_IMGBTN, Colours::Grey, WID_D_SELL_CHAIN), SetSpriteTip(SPR_SELL_CHAIN_TRAIN, STR_DEPOT_DRAG_WHOLE_TRAIN_TO_SELL_TOOLTIP), SetResize(0, 1), SetFill(0, 1),
82 NWidget(WWT_PUSHTXTBTN, Colours::Grey, WID_D_VEHICLE_LIST), SetAspect(WidgetDimensions::ASPECT_VEHICLE_ICON), SetFill(0, 1),
83 NWidget(WWT_PUSHIMGBTN, Colours::Grey, WID_D_STOP_ALL), SetSpriteTip(SPR_FLAG_VEH_STOPPED), SetAspect(WidgetDimensions::ASPECT_VEHICLE_FLAG), SetFill(0, 1),
84 NWidget(WWT_PUSHIMGBTN, Colours::Grey, WID_D_START_ALL), SetSpriteTip(SPR_FLAG_VEH_RUNNING), SetAspect(WidgetDimensions::ASPECT_VEHICLE_FLAG), SetFill(0, 1),
87};
88
91 WindowPosition::Automatic, "depot_train", 362, 123,
93 {},
95);
96
99 WindowPosition::Automatic, "depot_roadveh", 316, 97,
101 {},
103);
104
107 WindowPosition::Automatic, "depot_ship", 306, 99,
109 {},
111);
112
115 WindowPosition::Automatic, "depot_aircraft", 332, 99,
117 {},
119);
120
121extern void DepotSortList(VehicleList *list);
122
128void CcCloneVehicle(Commands, const CommandCost &result, VehicleID veh_id)
129{
130 if (result.Failed()) return;
131
132 const Vehicle *v = Vehicle::Get(veh_id);
133
135}
136
137static void TrainDepotMoveVehicle(const Vehicle *wagon, VehicleID sel, const Vehicle *head)
138{
139 const Vehicle *v = Vehicle::Get(sel);
140
141 if (v == wagon) return;
142
143 if (wagon == nullptr) {
144 if (head != nullptr) wagon = head->Last();
145 } else {
146 wagon = wagon->Previous();
147 if (wagon == nullptr) return;
148 }
149
150 if (wagon == v) return;
151
152 Command<Commands::MoveRailVehicle>::Post(STR_ERROR_CAN_T_MOVE_VEHICLE, v->tile, v->index, wagon == nullptr ? VehicleID::Invalid() : wagon->index, _ctrl_pressed);
153}
154
158
167{
168 switch (image_type) {
169 case EIT_IN_DEPOT: return _base_block_sizes_depot[type];
170 case EIT_PURCHASE: return _base_block_sizes_purchase[type];
171 default: NOT_REACHED();
172 }
173}
174
175static void InitBlocksizeForVehicles(VehicleType type, EngineImageType image_type)
176{
177 int max_extend_left = 0;
178 int max_extend_right = 0;
179 uint max_height = 0;
180
181 for (const Engine *e : Engine::IterateType(type)) {
182 if (!e->IsEnabled()) continue;
183
184 EngineID eid = e->index;
185 uint x, y;
186 int x_offs, y_offs;
187
188 switch (type) {
189 default: NOT_REACHED();
190 case VehicleType::Train: GetTrainSpriteSize(eid, x, y, x_offs, y_offs, image_type); break;
191 case VehicleType::Road: GetRoadVehSpriteSize(eid, x, y, x_offs, y_offs, image_type); break;
192 case VehicleType::Ship: GetShipSpriteSize(eid, x, y, x_offs, y_offs, image_type); break;
193 case VehicleType::Aircraft: GetAircraftSpriteSize(eid, x, y, x_offs, y_offs, image_type); break;
194 }
195 if (y > max_height) max_height = y;
196 if (-x_offs > max_extend_left) max_extend_left = -x_offs;
197 if ((int)x + x_offs > max_extend_right) max_extend_right = x + x_offs;
198 }
199
200 int min_extend = ScaleSpriteTrad(16);
201 int max_extend = ScaleSpriteTrad(98);
202
203 switch (image_type) {
204 case EIT_IN_DEPOT:
205 _base_block_sizes_depot[type].height = std::max<uint>(ScaleSpriteTrad(GetVehicleHeight(type)), max_height);
206 _base_block_sizes_depot[type].extend_left = Clamp(max_extend_left, min_extend, max_extend);
207 _base_block_sizes_depot[type].extend_right = Clamp(max_extend_right, min_extend, max_extend);
208 break;
209 case EIT_PURCHASE:
210 _base_block_sizes_purchase[type].height = std::max<uint>(ScaleSpriteTrad(GetVehicleHeight(type)), max_height);
211 _base_block_sizes_purchase[type].extend_left = Clamp(max_extend_left, min_extend, max_extend);
212 _base_block_sizes_purchase[type].extend_right = Clamp(max_extend_right, min_extend, max_extend);
213 break;
214
215 default: NOT_REACHED();
216 }
217}
218
224{
226 InitBlocksizeForVehicles(vt, EIT_IN_DEPOT);
227 InitBlocksizeForVehicles(vt, EIT_PURCHASE);
228 }
229
230 _consistent_train_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
231 bool first = true;
233 if (!e->IsEnabled()) continue;
234
235 uint w = TRAININFO_DEFAULT_VEHICLE_WIDTH;
236 if (e->GetGRF() != nullptr && IsCustomVehicleSpriteNum(e->VehInfo<RailVehicleInfo>().image_index)) {
237 w = e->GetGRF()->traininfo_vehicle_width;
238 if (w != VEHICLEINFO_FULL_VEHICLE_WIDTH) {
239 /* Hopeless.
240 * This is a NewGRF vehicle that uses TRAININFO_DEFAULT_VEHICLE_WIDTH.
241 * If the vehicles are shorter than 8/8 we have fractional lengths, which are not consistent after rounding.
242 */
244 break;
245 }
246 }
247
248 if (first) {
250 first = false;
251 } else if (w != _consistent_train_width) {
253 break;
254 }
255 }
256}
257
258static void DepotSellAllConfirmationCallback(Window *w, bool confirmed);
259const Sprite *GetAircraftSprite(EngineID engine);
260
261struct DepotWindow : Window {
262 VehicleID sel = VehicleID::Invalid();
263 VehicleID vehicle_over = VehicleID::Invalid();
265 bool generate_list = true;
266 bool check_unitnumber_digits = true;
268 VehicleList vehicle_list{};
269 VehicleList wagon_list{};
270 uint unitnumber_digits = 2;
271 uint num_columns = 1;
272 Scrollbar *hscroll = nullptr;
273 Scrollbar *vscroll = nullptr;
274 uint count_width = 0;
275 uint header_width = 0;
278 bool last_overlay_state = false;
279
280 DepotWindow(WindowDesc &desc, TileIndex tile, VehicleType type) : Window(desc)
281 {
282 assert(IsCompanyBuildableVehicleType(type)); // ensure that we make the call with a valid type
283
284 this->type = type;
285
286 this->CreateNestedTree();
287 this->hscroll = (this->type == VehicleType::Train ? this->GetScrollbar(WID_D_H_SCROLL) : nullptr);
288 this->vscroll = this->GetScrollbar(WID_D_V_SCROLL);
289 /* Don't show 'rename button' of aircraft hangar */
290 this->GetWidget<NWidgetStacked>(WID_D_SHOW_RENAME)->SetDisplayedPlane(type == VehicleType::Aircraft ? SZSP_NONE : 0);
291 /* Only train depots have a horizontal scrollbar and a 'sell chain' button */
292 if (type == VehicleType::Train) this->GetWidget<NWidgetCore>(WID_D_MATRIX)->SetMatrixDimension(1, 0 /* auto-scale */);
294 this->GetWidget<NWidgetStacked>(WID_D_SHOW_SELL_CHAIN)->SetDisplayedPlane(type == VehicleType::Train ? 0 : SZSP_NONE);
295 this->SetupWidgetData(type);
296 this->FinishInitNested(tile);
297
298 this->owner = GetTileOwner(tile);
300 }
301
302 void Close([[maybe_unused]] int data = 0) override
303 {
305 CloseWindowById(GetWindowClassForVehicleType(this->type), VehicleListIdentifier(VL_DEPOT_LIST, this->type, this->owner, this->GetDestinationIndex()).ToWindowNumber(), false);
307 this->Window::Close();
308 }
309
316 uint CountDraggedLength(const Train *t) const
317 {
318 /* Nothing is selected to add. */
319 if (this->sel == VehicleID::Invalid()) return 0;
320
321 /* Test if the dragged selection applies to this train. */
322 bool add_dragged = false;
323 for (const Train *u = t; u != nullptr; u = u->Next()) {
324 if (u->index == this->sel) return 0; // Selection is part of this train, so doesn't increase its length.
325 if (u->index == this->vehicle_over) add_dragged = true;
326 }
327
328 if (!add_dragged) return 0;
329
330 /* Sum the length of the dragged selection. */
331 uint length = 0;
332 for (Train *u = Train::Get(this->sel); u != nullptr; u = _cursor.vehchain ? u->Next() : (u->HasArticulatedPart() ? u->GetNextArticulatedPart() : nullptr)) {
333 length += u->gcache.cached_veh_length;
334 }
335
336 return length;
337 }
338
344 void DrawVehicleInDepot(const Vehicle *v, const Rect &r) const
345 {
346 bool free_wagon = false;
347
348 bool rtl = _current_text_dir == TD_RTL;
349 Rect text = r.Shrink(RectPadding::zero, WidgetDimensions::scaled.matrix); /* Ract for text elements, horizontal is already applied. */
350 Rect image = r.Indent(this->header_width, rtl).Indent(this->count_width, !rtl); /* Rect for vehicle images */
351
352 switch (v->type) {
353 case VehicleType::Train: {
354 const Train *u = Train::From(v);
355 free_wagon = u->IsFreeWagon();
356
357 uint x_space = free_wagon ?
358 ScaleSpriteTrad(_consistent_train_width != 0 ? _consistent_train_width : TRAININFO_DEFAULT_VEHICLE_WIDTH) :
359 0;
360
361 DrawTrainImage(u, image.Indent(x_space, rtl), this->sel, EIT_IN_DEPOT, free_wagon ? 0 : this->hscroll->GetPosition(), this->vehicle_over);
362
363 /* Length of consist in tiles with 1 fractional digit (rounded up) */
364 uint length = u->gcache.cached_total_length + this->CountDraggedLength(u);
365 Rect count = text.WithWidth(this->count_width - WidgetDimensions::scaled.hsep_normal, !rtl);
366 DrawString(count.left, count.right, count.bottom - GetCharacterHeight(FontSize::Small) + 1,
367 GetString(STR_JUST_DECIMAL, CeilDiv(length * 10, TILE_SIZE), 1),
368 TC_BLACK, SA_RIGHT | SA_FORCE, false, FontSize::Small); // Draw the counter
369 break;
370 }
371
372 case VehicleType::Road: DrawRoadVehImage(v, image, this->sel, EIT_IN_DEPOT); break;
373 case VehicleType::Ship: DrawShipImage(v, image, this->sel, EIT_IN_DEPOT); break;
374 case VehicleType::Aircraft: DrawAircraftImage(v, image, this->sel, EIT_IN_DEPOT); break;
375 default: NOT_REACHED();
376 }
377
378 uint diff_x, diff_y;
379 if (v->IsGroundVehicle()) {
380 /* Arrange unitnumber and flag horizontally */
381 diff_x = this->flag_size.width + WidgetDimensions::scaled.hsep_normal;
382 diff_y = WidgetDimensions::scaled.matrix.top;
383 } else {
384 /* Arrange unitnumber and flag vertically */
385 diff_x = 0;
387 }
388
389 text = text.WithWidth(this->header_width - WidgetDimensions::scaled.hsep_normal, rtl).WithHeight(GetCharacterHeight(FontSize::Normal)).Indent(diff_x, rtl);
390 if (free_wagon) {
391 DrawString(text, STR_DEPOT_NO_ENGINE);
392 } else {
393 Rect flag = r.WithWidth(this->flag_size.width, rtl).WithHeight(this->flag_size.height).Translate(0, diff_y);
394 DrawSpriteIgnorePadding((v->vehstatus.Test(VehState::Stopped)) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, flag, SA_CENTER);
395
396 DrawString(text, GetString(STR_JUST_COMMA, v->unitnumber), (v->max_age - CalendarTime::DAYS_IN_LEAP_YEAR) >= v->age ? TC_BLACK : TC_RED);
397 }
398 }
399
400 void DrawWidget(const Rect &r, WidgetID widget) const override
401 {
402 if (widget != WID_D_MATRIX) return;
403
404 bool rtl = _current_text_dir == TD_RTL;
405
406 /* Set the row and number of boxes in each row based on the number of boxes drawn in the matrix */
408
409 /* Set up rect for each cell */
410 Rect ir = r.WithHeight(this->resize.step_height);
411 if (this->num_columns != 1) ir = ir.WithWidth(this->resize.step_width, rtl);
412 ir = ir.Shrink(WidgetDimensions::scaled.framerect, RectPadding::zero);
413
414 /* Draw vertical separators at whole tiles.
415 * This only works in two cases:
416 * - All vehicles use VEHICLEINFO_FULL_VEHICLE_WIDTH as reference width.
417 * - All vehicles are 8/8. This cannot be checked for NewGRF, so instead we check for "all vehicles are original vehicles".
418 */
419 if (this->type == VehicleType::Train && _consistent_train_width != 0) {
422 Rect image = ir.Indent(this->header_width, rtl).Indent(this->count_width, !rtl);
423 int first_line = w + (-this->hscroll->GetPosition()) % w;
424 if (rtl) {
425 for (int x = image.right - first_line; x >= image.left; x -= w) {
426 GfxDrawLine(x, r.top, x, r.bottom, col, ScaleGUITrad(1), ScaleGUITrad(3));
427 }
428 } else {
429 for (int x = image.left + first_line; x <= image.right; x += w) {
430 GfxDrawLine(x, r.top, x, r.bottom, col, ScaleGUITrad(1), ScaleGUITrad(3));
431 }
432 }
433 }
434
435 uint16_t rows_in_display = wid->current_y / wid->resize_y;
436
437 uint num = this->vscroll->GetPosition() * this->num_columns;
438 uint maxval = static_cast<uint>(std::min<size_t>(this->vehicle_list.size(), num + (rows_in_display * this->num_columns)));
439 for (; num < maxval; ir = ir.Translate(0, this->resize.step_height)) { // Draw the rows
440 Rect cell = ir; /* Keep track of horizontal cells */
441 for (uint i = 0; i < this->num_columns && num < maxval; i++, num++) {
442 /* Draw all vehicles in the current row */
443 const Vehicle *v = this->vehicle_list[num];
444 this->DrawVehicleInDepot(v, cell);
445 cell = cell.Translate(rtl ? -(int)this->resize.step_width : (int)this->resize.step_width, 0);
446 }
447 }
448
449 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)));
450
451 /* Draw the train wagons without an engine in front. */
452 for (; num < maxval; num++, ir = ir.Translate(0, this->resize.step_height)) {
453 const Vehicle *v = this->wagon_list[num - this->vehicle_list.size()];
454 this->DrawVehicleInDepot(v, ir);
455 }
456 }
457
458 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
459 {
460 if (widget == WID_D_CAPTION) return GetString(STR_DEPOT_CAPTION, this->type, this->GetDestinationIndex());
461
462 return this->Window::GetWidgetString(widget, stringid);
463 }
464
472
476 const Vehicle *vehicle = nullptr;
477 const Vehicle *wagon = nullptr;
478 };
479
487 {
488 this->RefreshVehicleList();
489
490 const NWidgetCore *matrix_widget = this->GetWidget<NWidgetCore>(WID_D_MATRIX);
491 /* Make X relative to widget. Y is left alone for GetScrolledRowFromWidget(). */
492 x -= matrix_widget->pos_x;
493 /* In case of RTL the widgets are swapped as a whole */
494 if (_current_text_dir == TD_RTL) x = matrix_widget->current_x - x;
495
496 uint xt = 0, xm = 0, ym = 0;
497 if (this->type == VehicleType::Train) {
498 xm = x;
499 } else {
500 xt = x / this->resize.step_width;
501 xm = x % this->resize.step_width;
502 if (xt >= this->num_columns) return {.action = DepotGUIAction::Error};
503 }
504 ym = (y - matrix_widget->pos_y) % this->resize.step_height;
505
506 int32_t row = this->vscroll->GetScrolledRowFromWidget(y, this, WID_D_MATRIX);
507 uint pos = (row * this->num_columns) + xt;
508
509 if (row == INT32_MAX || this->vehicle_list.size() + this->wagon_list.size() <= pos) {
510 /* Clicking on 'line' / 'block' without a vehicle */
511 if (this->type == VehicleType::Train) {
512 /* End the dragging */
513 return {.action = DepotGUIAction::DragVehicle};
514 } else {
515 return {.action = DepotGUIAction::Error}; // empty block, so no vehicle is selected
516 }
517 }
518
519 const Vehicle *vehicle;
520 bool is_wagon = false;
521 if (this->vehicle_list.size() > pos) {
522 vehicle = this->vehicle_list[pos];
523 /* Skip vehicles that are scrolled off the list */
524 if (this->type == VehicleType::Train) x += this->hscroll->GetPosition();
525 } else {
526 pos -= (uint)this->vehicle_list.size();
527 vehicle = this->wagon_list[pos];
528 /* free wagons don't have an initial loco. */
529 x -= ScaleSpriteTrad(VEHICLEINFO_FULL_VEHICLE_WIDTH);
530 is_wagon = true;
531 }
532
533 if (xm <= this->header_width) {
534 switch (this->type) {
536 if (is_wagon) return {.action = DepotGUIAction::Error};
537 [[fallthrough]];
538
540 if (xm <= this->flag_size.width) return {.action = DepotGUIAction::StartStop, .vehicle = vehicle};
541 break;
542
545 if (xm <= this->flag_size.width && ym >= (uint)(GetCharacterHeight(FontSize::Normal) + WidgetDimensions::scaled.vsep_normal)) return {.action = DepotGUIAction::StartStop, .vehicle = vehicle};
546 break;
547
548 default: NOT_REACHED();
549 }
550 return {.action = DepotGUIAction::ShowVehicle, .vehicle = vehicle};
551 }
552
553 if (this->type != VehicleType::Train) return {.action = DepotGUIAction::DragVehicle, .vehicle = vehicle};
554
555 /* Clicking on the counter */
556 if (xm >= matrix_widget->current_x - this->count_width) {
557 if (is_wagon) return {.action = DepotGUIAction::Error};
558 return {.action = DepotGUIAction::ShowVehicle, .vehicle = vehicle};
559 }
560
561 /* Account for the header */
562 x -= this->header_width;
563
564 /* find the vehicle in this row that was clicked */
565 const Train *wagon = Train::From(vehicle);
566 for (; wagon != nullptr; wagon = wagon->Next()) {
567 x -= wagon->GetDisplayImageWidth();
568 if (x < 0) break;
569 }
570
571 return {.action = DepotGUIAction::DragVehicle, .vehicle = vehicle, .wagon = wagon != nullptr ? wagon->GetFirstEnginePart() : nullptr};
572 }
573
579 void DepotClick(int x, int y)
580 {
581 DepotActionResult result = this->GetVehicleFromDepotWndPt(x, y);
582 switch (result.action) {
583 case DepotGUIAction::Error: // invalid
584 return;
585
586 case DepotGUIAction::DragVehicle: { // start dragging of vehicle
587 const Vehicle *v = (this->type == VehicleType::Train) ? result.wagon : result.vehicle;
588
589 if (v != nullptr && VehicleClicked(v)) return;
590
591 VehicleID sel = this->sel;
592
593 if (this->type == VehicleType::Train && sel != VehicleID::Invalid()) {
594 this->sel = VehicleID::Invalid();
595 TrainDepotMoveVehicle(v, sel, result.vehicle);
596 } else if (v != nullptr) {
599 _cursor.vehchain = _ctrl_pressed;
600
601 this->sel = v->index;
602 this->SetDirty();
603 }
604 break;
605 }
606
607 case DepotGUIAction::ShowVehicle: // show info window
609 break;
610
611 case DepotGUIAction::StartStop: // click start/stop flag
612 StartStopVehicle(result.vehicle, false);
613 break;
614
615 default: NOT_REACHED();
616 }
617 }
618
627 {
628 this->GetWidget<NWidgetCore>(WID_D_STOP_ALL)->SetToolTip(STR_DEPOT_MASS_STOP_DEPOT_TRAIN_TOOLTIP + to_underlying(type));
629 this->GetWidget<NWidgetCore>(WID_D_START_ALL)->SetToolTip(STR_DEPOT_MASS_START_DEPOT_TRAIN_TOOLTIP + to_underlying(type));
630 this->GetWidget<NWidgetCore>(WID_D_SELL)->SetToolTip(STR_DEPOT_TRAIN_SELL_TOOLTIP + to_underlying(type));
631 this->GetWidget<NWidgetCore>(WID_D_SELL_ALL)->SetToolTip(STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TOOLTIP + to_underlying(type));
632
633 this->GetWidget<NWidgetCore>(WID_D_BUILD)->SetStringTip(STR_DEPOT_TRAIN_NEW_VEHICLES_BUTTON + to_underlying(type), STR_DEPOT_TRAIN_NEW_VEHICLES_TOOLTIP + to_underlying(type));
634 this->GetWidget<NWidgetCore>(WID_D_CLONE)->SetStringTip(STR_DEPOT_CLONE_TRAIN + to_underlying(type), STR_DEPOT_CLONE_TRAIN_DEPOT_TOOLTIP + to_underlying(type));
635
636 this->GetWidget<NWidgetCore>(WID_D_LOCATION)->SetToolTip(STR_DEPOT_TRAIN_LOCATION_TOOLTIP + to_underlying(type));
637 this->GetWidget<NWidgetCore>(WID_D_VEHICLE_LIST)->SetToolTip(STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TOOLTIP + to_underlying(type));
638 this->GetWidget<NWidgetCore>(WID_D_AUTOREPLACE)->SetToolTip(STR_DEPOT_AUTOREPLACE_TRAIN_TOOLTIP + to_underlying(type));
639 this->GetWidget<NWidgetCore>(WID_D_MATRIX)->SetToolTip(STR_DEPOT_TRAIN_LIST_TOOLTIP + to_underlying(type));
640
641 switch (type) {
642 default: NOT_REACHED();
643
645 this->GetWidget<NWidgetCore>(WID_D_VEHICLE_LIST)->SetString(STR_TRAIN);
646
647 /* Sprites */
648 this->GetWidget<NWidgetCore>(WID_D_SELL)->SetSprite(SPR_SELL_TRAIN);
649 this->GetWidget<NWidgetCore>(WID_D_SELL_ALL)->SetSprite(SPR_SELL_ALL_TRAIN);
650 this->GetWidget<NWidgetCore>(WID_D_AUTOREPLACE)->SetSprite(SPR_REPLACE_TRAIN);
651 break;
652
654 this->GetWidget<NWidgetCore>(WID_D_VEHICLE_LIST)->SetString(STR_LORRY);
655
656 /* Sprites */
657 this->GetWidget<NWidgetCore>(WID_D_SELL)->SetSprite(SPR_SELL_ROADVEH);
658 this->GetWidget<NWidgetCore>(WID_D_SELL_ALL)->SetSprite(SPR_SELL_ALL_ROADVEH);
659 this->GetWidget<NWidgetCore>(WID_D_AUTOREPLACE)->SetSprite(SPR_REPLACE_ROADVEH);
660 break;
661
663 this->GetWidget<NWidgetCore>(WID_D_VEHICLE_LIST)->SetString(STR_SHIP);
664
665 /* Sprites */
666 this->GetWidget<NWidgetCore>(WID_D_SELL)->SetSprite(SPR_SELL_SHIP);
667 this->GetWidget<NWidgetCore>(WID_D_SELL_ALL)->SetSprite(SPR_SELL_ALL_SHIP);
668 this->GetWidget<NWidgetCore>(WID_D_AUTOREPLACE)->SetSprite(SPR_REPLACE_SHIP);
669 break;
670
672 this->GetWidget<NWidgetCore>(WID_D_VEHICLE_LIST)->SetString(STR_PLANE);
673
674 /* Sprites */
675 this->GetWidget<NWidgetCore>(WID_D_SELL)->SetSprite(SPR_SELL_AIRCRAFT);
676 this->GetWidget<NWidgetCore>(WID_D_SELL_ALL)->SetSprite(SPR_SELL_ALL_AIRCRAFT);
677 this->GetWidget<NWidgetCore>(WID_D_AUTOREPLACE)->SetSprite(SPR_REPLACE_AIRCRAFT);
678 break;
679 }
680 }
681
682 void OnInit() override
683 {
684 this->cell_size = GetVehicleImageCellSize(this->type, EIT_IN_DEPOT);
685 this->flag_size = maxdim(GetScaledSpriteSize(SPR_FLAG_VEH_STOPPED), GetScaledSpriteSize(SPR_FLAG_VEH_RUNNING));
686 }
687
688 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
689 {
690 switch (widget) {
691 case WID_D_MATRIX: {
692 uint min_height = 0;
693
694 if (this->type == VehicleType::Train) {
695 this->count_width = GetStringBoundingBox(GetString(STR_JUST_DECIMAL, GetParamMaxValue(1000, 0, FontSize::Small), 1), FontSize::Small).width + WidgetDimensions::scaled.hsep_normal;
696 } else {
697 this->count_width = 0;
698 }
699
700 Dimension unumber = GetStringBoundingBox(GetString(STR_JUST_COMMA, GetParamMaxDigits(this->unitnumber_digits)));
701
702 if (this->type == VehicleType::Train || this->type == VehicleType::Road) {
703 min_height = std::max<uint>(unumber.height, this->flag_size.height);
704 this->header_width = unumber.width + WidgetDimensions::scaled.hsep_normal + this->flag_size.width + WidgetDimensions::scaled.hsep_normal;
705 } else {
706 min_height = unumber.height + WidgetDimensions::scaled.vsep_normal + this->flag_size.height;
707 this->header_width = std::max<uint>(unumber.width, this->flag_size.width) + WidgetDimensions::scaled.hsep_normal;
708 }
709 int base_width = this->count_width + this->header_width + padding.width;
710
711 resize.height = std::max<uint>(this->cell_size.height, min_height + padding.height);
712 if (this->type == VehicleType::Train) {
713 resize.width = 1;
714 size.width = base_width + 2 * ScaleSpriteTrad(29); // about 2 parts
715 size.height = resize.height * 6;
716 } else {
717 resize.width = base_width + this->cell_size.extend_left + this->cell_size.extend_right;
718 size.width = resize.width * (this->type == VehicleType::Road ? 5 : 3);
719 size.height = resize.height * (this->type == VehicleType::Road ? 5 : 3);
720 }
721 fill.width = resize.width;
722 fill.height = resize.height;
723 break;
724 }
725 }
726 }
727
733 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
734 {
735 this->generate_list = true;
736 }
737
738 void RefreshVehicleList()
739 {
740 if (this->generate_list) {
741 /* Generate the vehicle list
742 * It's ok to use the wagon pointers for non-trains as they will be ignored */
743 BuildDepotVehicleList(this->type, TileIndex(this->window_number), &this->vehicle_list, &this->wagon_list);
744 this->generate_list = false;
745 DepotSortList(&this->vehicle_list);
746
747 this->check_unitnumber_digits = true;
748 }
749 }
750
751 void OnPaint() override
752 {
753 this->RefreshVehicleList();
754
755 if (this->check_unitnumber_digits) {
756 this->check_unitnumber_digits = false;
757 uint new_unitnumber_digits = GetUnitNumberDigits(this->vehicle_list);
758 /* Only increase the size; do not decrease to prevent constant changes */
759 if (this->unitnumber_digits < new_unitnumber_digits) {
760 this->unitnumber_digits = new_unitnumber_digits;
761 this->ReInit();
762 }
763 }
764
765 /* determine amount of items for scroller */
766 if (this->type == VehicleType::Train) {
767 uint max_width = ScaleSpriteTrad(VEHICLEINFO_FULL_VEHICLE_WIDTH);
768 for (uint num = 0; num < this->vehicle_list.size(); num++) {
769 uint width = 0;
770 for (const Train *v = Train::From(this->vehicle_list[num]); v != nullptr; v = v->Next()) {
771 width += v->GetDisplayImageWidth();
772 }
773 max_width = std::max(max_width, width);
774 }
775 /* Always have 1 empty row, so people can change the setting of the train */
776 this->vscroll->SetCount(this->vehicle_list.size() + this->wagon_list.size() + 1);
777 /* 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 */
778 this->hscroll->SetCount(max_width + ScaleSpriteTrad(2 * VEHICLEINFO_FULL_VEHICLE_WIDTH + 1));
779 } else {
780 this->vscroll->SetCount(CeilDiv((uint)this->vehicle_list.size(), this->num_columns));
781 }
782
783 /* Setup disabled buttons. */
784 TileIndex tile(this->window_number);
795
796 this->DrawWidgets();
797 }
798
799 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
800 {
801 switch (widget) {
802 case WID_D_MATRIX: // List
803 this->DepotClick(pt.x, pt.y);
804 break;
805
806 case WID_D_BUILD: // Build vehicle
808 ShowBuildVehicleWindow(TileIndex(this->window_number), this->type);
809 break;
810
811 case WID_D_CLONE: // Clone button
814
815 if (this->IsWidgetLowered(WID_D_CLONE)) {
816 static constexpr VehicleTypeIndexArray<const CursorID> clone_icons = {
817 SPR_CURSOR_CLONE_TRAIN, SPR_CURSOR_CLONE_ROADVEH,
818 SPR_CURSOR_CLONE_SHIP, SPR_CURSOR_CLONE_AIRPLANE
819 };
820
821 SetObjectToPlaceWnd(clone_icons[this->type], PAL_NONE, HT_VEHICLE, this);
822 } else {
824 }
825 SndClickBeep();
826 break;
827
828 case WID_D_LOCATION:
829 if (_ctrl_pressed) {
831 } else {
833 }
834 break;
835
836 case WID_D_RENAME: // Rename button
837 ShowQueryString(GetString(STR_DEPOT_NAME, this->type, Depot::GetByTile(TileIndex(this->window_number))->index), STR_DEPOT_RENAME_DEPOT_CAPTION,
839 break;
840
841 case WID_D_STOP_ALL:
842 case WID_D_START_ALL: {
843 VehicleListIdentifier vli(VL_DEPOT_LIST, this->type, this->owner);
844 Command<Commands::MassStartStop>::Post(TileIndex(this->window_number), widget == WID_D_START_ALL, false, vli);
845 break;
846 }
847
848 case WID_D_SELL_ALL:
849 /* Only open the confirmation window if there are anything to sell */
850 if (!this->vehicle_list.empty() || !this->wagon_list.empty()) {
851 ShowQuery(
852 GetEncodedString(STR_DEPOT_CAPTION, this->type, this->GetDestinationIndex()),
853 GetEncodedString(STR_DEPOT_SELL_CONFIRMATION_TEXT),
854 this,
855 DepotSellAllConfirmationCallback
856 );
857 }
858 break;
859
861 ShowVehicleListWindow(GetTileOwner(this->window_number), this->type, TileIndex(this->window_number));
862 break;
863
865 Command<Commands::DepotMassAutoreplace>::Post(GetCmdAutoreplaceVehMsg(this->type), TileIndex(this->window_number), this->type);
866 break;
867
868 }
869 }
870
871 void OnQueryTextFinished(std::optional<std::string> str) override
872 {
873 if (!str.has_value()) return;
874
875 /* Do depot renaming */
876 Command<Commands::RenameDepot>::Post(STR_ERROR_CAN_T_RENAME_DEPOT, this->GetDestinationIndex().ToDepotID(), *str);
877 }
878
879 bool OnRightClick([[maybe_unused]] Point pt, WidgetID widget) override
880 {
881 if (widget != WID_D_MATRIX) return false;
882
883 DepotActionResult result = this->GetVehicleFromDepotWndPt(pt.x, pt.y);
884 const Vehicle *v = this->type == VehicleType::Train ? result.wagon : result.vehicle;
885 if (result.action != DepotGUIAction::DragVehicle || v == nullptr) return false;
886
887 CargoArray capacity{}, loaded{};
888
889 /* Display info for single (articulated) vehicle, or for whole chain starting with selected vehicle */
890 bool whole_chain = (this->type == VehicleType::Train && _ctrl_pressed);
891
892 /* loop through vehicle chain and collect cargoes */
893 uint num = 0;
894 for (const Vehicle *w = v; w != nullptr; w = w->Next()) {
895 if (w->cargo_cap > 0 && w->cargo_type < NUM_CARGO) {
896 capacity[w->cargo_type] += w->cargo_cap;
897 loaded [w->cargo_type] += w->cargo.StoredCount();
898 }
899
900 if (w->type == VehicleType::Train && !w->HasArticulatedPart()) {
901 num++;
902 if (!whole_chain) break;
903 }
904 }
905
906 /* Build tooltipstring */
907 static std::string details;
908 details.clear();
909
910 for (const CargoSpec *cs : _sorted_cargo_specs) {
911 CargoType cargo_type = cs->Index();
912 if (capacity[cargo_type] == 0) continue;
913
914 auto params = MakeParameters(cargo_type, loaded[cargo_type], cargo_type, capacity[cargo_type]);
915 AppendStringWithArgsInPlace(details, STR_DEPOT_VEHICLE_TOOLTIP_CARGO, params);
916 }
917
918 /* Show tooltip window */
919 if (whole_chain) {
920 GuiShowTooltips(this, GetEncodedString(STR_DEPOT_VEHICLE_TOOLTIP_CHAIN, num, details), TCC_RIGHT_CLICK);
921 } else {
922 GuiShowTooltips(this, GetEncodedString(STR_DEPOT_VEHICLE_TOOLTIP, v->engine_type, details), TCC_RIGHT_CLICK);
923 }
924
925 return true;
926 }
927
933 bool OnVehicleSelect(const Vehicle *v) override
934 {
935 if (_ctrl_pressed) {
936 /* Share-clone, do not open new viewport, and keep tool active */
937 Command<Commands::CloneVehicle>::Post(STR_ERROR_CAN_T_BUY_TRAIN + to_underlying(v->type), TileIndex(this->window_number), v->index, true);
938 } else {
939 /* Copy-clone, open viewport for new vehicle, and deselect the tool (assume player wants to change things on new vehicle) */
940 if (Command<Commands::CloneVehicle>::Post(STR_ERROR_CAN_T_BUY_TRAIN + to_underlying(v->type), CcCloneVehicle, TileIndex(this->window_number), v->index, false)) {
942 }
943 }
944
945 return true;
946 }
947
956 bool OnVehicleSelect(VehicleList::const_iterator begin, VehicleList::const_iterator end) override
957 {
958 if (!_ctrl_pressed) {
959 /* If CTRL is not pressed: If all the vehicles in this list have the same orders, then copy orders */
960 if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
961 return VehiclesHaveSameEngineList(v1, v2);
962 })) {
963 if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
964 return VehiclesHaveSameOrderList(v1, v2);
965 })) {
966 OnVehicleSelect(*begin);
967 } else {
968 ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_BUY_TRAIN + to_underlying((*begin)->type)),
969 GetEncodedString(STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST), WL_INFO);
970 }
971 } else {
972 ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_BUY_TRAIN + to_underlying((*begin)->type)),
973 GetEncodedString(STR_ERROR_CAN_T_CLONE_VEHICLE_LIST), WL_INFO);
974 }
975 } else {
976 /* If CTRL is pressed: If all the vehicles in this list share orders, then copy orders */
977 if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
978 return VehiclesHaveSameEngineList(v1, v2);
979 })) {
980 if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
981 return v1->FirstShared() == v2->FirstShared();
982 })) {
983 OnVehicleSelect(*begin);
984 } else {
985 ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_BUY_TRAIN + to_underlying((*begin)->type)),
986 GetEncodedString(STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST), WL_INFO);
987 }
988 } else {
989 ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_BUY_TRAIN + to_underlying((*begin)->type)),
990 GetEncodedString(STR_ERROR_CAN_T_CLONE_VEHICLE_LIST), WL_INFO);
991 }
992 }
993
994 return true;
995 }
996
997 void OnPlaceObjectAbort() override
998 {
999 /* abort clone */
1000 this->RaiseWidget(WID_D_CLONE);
1002
1003 /* abort drag & drop */
1004 this->sel = VehicleID::Invalid();
1005 this->vehicle_over = VehicleID::Invalid();
1007
1008 if (this->hovered_widget != INVALID_WIDGET) {
1009 this->SetWidgetLoweredState(this->hovered_widget, false);
1010 this->SetWidgetDirty(this->hovered_widget);
1011 this->hovered_widget = INVALID_WIDGET;
1012 }
1013 }
1014
1015 void OnMouseLoop() override
1016 {
1017 if (last_overlay_state != ShowCargoIconOverlay()) {
1018 last_overlay_state = ShowCargoIconOverlay();
1019 this->SetDirty();
1020 }
1021 }
1022
1023 void OnMouseDrag(Point pt, WidgetID widget) override
1024 {
1025 if (this->sel == VehicleID::Invalid()) return;
1026 if (widget != this->hovered_widget) {
1027 if (this->hovered_widget == WID_D_SELL || this->hovered_widget == WID_D_SELL_CHAIN) {
1028 this->SetWidgetLoweredState(this->hovered_widget, false);
1029 this->SetWidgetDirty(this->hovered_widget);
1030 }
1031 this->hovered_widget = widget;
1032 if (this->hovered_widget == WID_D_SELL || this->hovered_widget == WID_D_SELL_CHAIN) {
1033 this->SetWidgetLoweredState(this->hovered_widget, true);
1034 this->SetWidgetDirty(this->hovered_widget);
1035 }
1036 }
1037 if (this->type != VehicleType::Train) return;
1038
1039 /* A rail vehicle is dragged.. */
1040 if (widget != WID_D_MATRIX) { // ..outside of the depot matrix.
1041 if (this->vehicle_over != VehicleID::Invalid()) {
1042 this->vehicle_over = VehicleID::Invalid();
1044 }
1045 return;
1046 }
1047
1048 DepotActionResult result = this->GetVehicleFromDepotWndPt(pt.x, pt.y);
1049 if (result.action != DepotGUIAction::DragVehicle) return;
1050
1051 VehicleID new_vehicle_over = VehicleID::Invalid();
1052 if (result.vehicle != nullptr) {
1053 if (result.wagon == nullptr && result.vehicle->Last()->index != this->sel) { // ..at the end of the train.
1054 /* 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
1055 * destination inside a train. This head index is then used to indicate that a wagon is inserted at
1056 * the end of the train.
1057 */
1058 new_vehicle_over = result.vehicle->index;
1059 } else if (result.wagon != nullptr && result.vehicle != result.wagon &&
1060 result.wagon->index != this->sel &&
1061 result.wagon->Previous()->index != this->sel) { // ..over an existing wagon.
1062 new_vehicle_over = result.wagon->index;
1063 }
1064 }
1065
1066 if (this->vehicle_over == new_vehicle_over) return;
1067
1068 this->vehicle_over = new_vehicle_over;
1069 this->SetWidgetDirty(widget);
1070 }
1071
1072 void OnDragDrop(Point pt, WidgetID widget) override
1073 {
1074 switch (widget) {
1075 case WID_D_MATRIX: {
1076 DepotActionResult result = this->GetVehicleFromDepotWndPt(pt.x, pt.y);
1077 VehicleID sel = this->sel;
1078
1079 this->sel = VehicleID::Invalid();
1080 this->SetDirty();
1081
1082 if (this->type == VehicleType::Train) {
1083 if (result.action == DepotGUIAction::DragVehicle && sel != VehicleID::Invalid()) {
1084 if (result.wagon != nullptr && result.wagon->index == sel && _ctrl_pressed) {
1085 Command<Commands::ReverseTrainDirection>::Post(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE, Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true);
1086 } else if (result.wagon == nullptr || result.wagon->index != sel) {
1087 this->vehicle_over = VehicleID::Invalid();
1088 TrainDepotMoveVehicle(result.wagon, sel, result.vehicle);
1089 } else if (result.vehicle != nullptr && result.vehicle->IsFrontEngine()) {
1091 }
1092 }
1093 } else if (result.action == DepotGUIAction::DragVehicle && result.vehicle != nullptr && sel == result.vehicle->index) {
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 == VehicleType::Train && (widget == WID_D_SELL_CHAIN || _ctrl_pressed));
1110 Command<Commands::SellVehicle>::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);
1128 }
1129 if (this->GetWidget<NWidgetBase>(WID_D_SELL) != nullptr && !this->IsWidgetDisabled(WID_D_SELL_CHAIN)) {
1132 }
1133 }
1134
1135 void OnResize() override
1136 {
1137 this->vscroll->SetCapacityFromWidget(this, WID_D_MATRIX);
1139 if (this->type == VehicleType::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
1147 {
1148 if (this->sel != VehicleID::Invalid()) {
1149 _cursor.vehchain = _ctrl_pressed;
1151 return ES_HANDLED;
1152 }
1153
1154 return ES_NOT_HANDLED;
1155 }
1156
1163 {
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<Commands::DepotMassSell>::Post(GetCmdSellAllVehMsg(vehtype), tile, vehtype);
1175 }
1176}
1177
1184{
1185 if (BringWindowToFrontById(WC_VEHICLE_DEPOT, tile) != nullptr) return;
1186
1187 switch (type) {
1188 default: NOT_REACHED();
1189 case VehicleType::Train: new DepotWindow(_train_depot_desc, tile, type); break;
1190 case VehicleType::Road: new DepotWindow(_road_depot_desc, tile, type); break;
1191 case VehicleType::Ship: new DepotWindow(_ship_depot_desc, tile, type); break;
1192 case VehicleType::Aircraft: new DepotWindow(_aircraft_depot_desc, tile, type); break;
1193 }
1194}
1195
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}
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.
static constexpr CargoType NUM_CARGO
Maximum number of cargo types in a game.
Definition cargo_type.h:75
CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:22
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?
static Pool::IterateWrapperFiltered< Engine, EngineTypeFilter > IterateType(VehicleType vt, size_t from=0)
Returns an iterable ensemble of all valid engines of the given type.
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:2458
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:2532
size_type GetPosition() const
Gets the position of the first visible element in the list.
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:30
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.
static VehicleTypeIndexArray< VehicleCellSize > _base_block_sizes_purchase
Cell size for vehicle images in the purchase list.
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 WindowDesc _road_depot_desc(WindowPosition::Automatic, "depot_roadveh", 316, 97, WC_VEHICLE_DEPOT, WC_NONE, {}, _nested_train_depot_widgets)
Window definition for the road depot window.
static WindowDesc _train_depot_desc(WindowPosition::Automatic, "depot_train", 362, 123, WC_VEHICLE_DEPOT, WC_NONE, {}, _nested_train_depot_widgets)
Window definition for the train depot window.
static uint _consistent_train_width
Whether trains of all lengths are consistently scaled. Either TRAININFO_DEFAULT_VEHICLE_WIDTH,...
static WindowDesc _ship_depot_desc(WindowPosition::Automatic, "depot_ship", 306, 99, WC_VEHICLE_DEPOT, WC_NONE, {}, _nested_train_depot_widgets)
Window definition for the ship depot window.
void DeleteDepotHighlightOfVehicle(const Vehicle *v)
Removes the highlight of a vehicle in a depot window.
static constexpr std::initializer_list< NWidgetPart > _nested_train_depot_widgets
Nested widget definition for train depots.
Definition depot_gui.cpp:50
static VehicleTypeIndexArray< VehicleCellSize > _base_block_sizes_depot
Cell size for vehicle images in the depot view.
static WindowDesc _aircraft_depot_desc(WindowPosition::Automatic, "depot_aircraft", 332, 99, WC_VEHICLE_DEPOT, WC_NONE, {}, _nested_train_depot_widgets)
Window definition for the aircraft depot window.
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.
DestinationID GetDepotDestinationIndex(Tile t)
Get the destination index of a 'depot'.
Definition depot_map.h:69
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.
PoolID< uint16_t, struct EngineIDTag, 64000, 0xFFFF > EngineID
Unique identification number of an engine.
Definition engine_type.h:26
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Definition enum_type.hpp:21
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:88
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:900
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:669
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:39
Dimension GetScaledSpriteSize(SpriteID sprid)
Scale sprite size for GUI.
Definition widget.cpp:70
@ Small
Index of the small font in the font tables.
Definition gfx_type.h:250
@ Normal
Index of the normal font in the font tables.
Definition gfx_type.h:249
@ SA_RIGHT
Right align the text (must be a single bit).
Definition gfx_type.h:390
@ SA_FORCE
Force the alignment, i.e. don't swap for RTL languages.
Definition gfx_type.h:400
@ SA_CENTER
Center both horizontally and vertically.
Definition gfx_type.h:398
@ Invalid
Invalid marker.
Definition gfx_type.h:302
@ Grey
Grey.
Definition gfx_type.h:299
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 EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=INVALID_WIDGET)
Widget part function for starting a new 'real' widget.
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:980
GUI functions that shouldn't be here.
void ShowExtraViewportWindow(TileIndex tile=INVALID_TILE)
Show a new Extra Viewport window.
#define Point
Macro that prevents name conflicts between included headers.
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:690
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.
PixelColour GetColourGradient(Colours colour, Shade shade)
Get colour gradient palette index.
Definition palette.cpp:393
@ Normal
Normal colour shade.
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
void SndClickBeep()
Play a beep sound for a click event if enabled in settings.
Definition sound.cpp:253
Functions related to sound.
Types related to the sprite cache.
static const CursorID SPR_CURSOR_MOUSE
Cursor sprite numbers.
Definition sprites.h:1404
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:236
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:424
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:56
uint64_t GetParamMaxDigits(uint count, FontSize size)
Get some number that is suitable for string size computations.
Definition strings.cpp:218
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:117
Specification of a cargo type.
Definition cargotype.h:75
T y
Y coordinate.
T x
X coordinate.
Result of GetVehicleFromDepotWndPt that tries to determine the action to perform.
const Vehicle * wagon
The wagon to perform the action on. Only set for DragVehicle actions on trains.
DepotGUIAction action
Action to perform.
const Vehicle * vehicle
The vehicle, or head of vehicle, to perform the action on.
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.
DepotActionResult GetVehicleFromDepotWndPt(int x, int y)
Determine what action to take for clicking at the given location in the depot window.
DepotGUIAction
Action to perform when using the depot UI.
@ ShowVehicle
Show the vehicle window.
@ Error
Most likely clicked outside of the bounds.
@ DragVehicle
Drag a vehicle to somewhere else.
@ StartStop
Start/stop the vehicle.
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. INVALID_WIDGET 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.
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).
static void Reset(TileIndex tile=INVALID_TILE, bool from_gui=true)
Reset the OrderBackups from GUI/game logic.
Colour for pixel/line drawing.
Definition gfx_type.h:414
static Vehicle * Get(auto index)
Information about a rail vehicle.
Definition engine_type.h:74
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.
T * Next() const
Get next vehicle in the chain.
static Train * From(Vehicle *v)
T * GetFirstEnginePart()
Get the first part of an articulated engine.
Data structure describing a sprite.
'Train' is either a loco or a wagon.
Definition train.h:97
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.
bool IsGroundVehicle() const
Check if the vehicle is a ground vehicle.
VehStates vehstatus
Status.
Vehicle * Next() const
Get the next vehicle of this vehicle.
bool IsFrontEngine() const
Check if the vehicle is a front engine.
TimerGameCalendar::Date age
Age in calendar days.
TimerGameCalendar::Date max_age
Maximum age.
Vehicle * FirstShared() const
Get the first vehicle of this vehicle chain.
Vehicle * Previous() const
Get the previous vehicle of this vehicle.
Vehicle * Last() const
Get the last vehicle of this vehicle chain.
TileIndex tile
Current tile index.
UnitID unitnumber
unit number, for display purposes only
High level window description.
Definition window_gui.h:168
Data structure for an opened window.
Definition window_gui.h:274
void ReInit(int rx=0, int ry=0, bool reposition=false)
Re-initialize a window, and optionally change its size.
Definition window.cpp:992
virtual void Close(int data=0)
Hide the window and all its child windows, and mark them for a later deletion.
Definition window.cpp:1117
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1822
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:786
void RaiseWidget(WidgetID widget_index)
Marks a widget as raised.
Definition window_gui.h:470
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:570
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
Definition window.cpp:518
ResizeInfo resize
Resize information.
Definition window_gui.h:315
void SetWidgetsDisabledState(bool disab_stat, Args... widgets)
Sets the enabled/disabled status of a list of widgets.
Definition window_gui.h:516
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1812
bool IsWidgetLowered(WidgetID widget_index) const
Gets the lowered state of a widget.
Definition window_gui.h:492
bool IsWidgetDisabled(WidgetID widget_index) const
Gets the enabled/disabled status of a widget.
Definition window_gui.h:411
Owner owner
The owner of the content shown in this window. Company colour is acquired from this variable.
Definition window_gui.h:317
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition window_gui.h:442
Window(WindowDesc &desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
Definition window.cpp:1846
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:990
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:609
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition window.cpp:327
int width
width of the window (number of pixels to the right in x direction)
Definition window_gui.h:312
void ToggleWidgetLoweredState(WidgetID widget_index)
Invert the lowered/raised status of a widget.
Definition window_gui.h:451
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:303
Stuff related to the text buffer GUI.
@ EnableDefault
enable the 'Default' button ("\0" is returned)
Definition textbuf_gui.h:20
@ LengthIsInChars
the length of the string is counted in characters
Definition textbuf_gui.h:21
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
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:92
static constexpr uint TILE_SIZE
Tile size in world coordinates.
Definition tile_type.h:15
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:99
bool VehiclesHaveSameEngineList(const Vehicle *v1, const Vehicle *v2)
Checks if two vehicle chains have the same list of engines.
Definition vehicle.cpp:3308
bool VehiclesHaveSameOrderList(const Vehicle *v1, const Vehicle *v2)
Checks if two vehicles have the same list of orders.
Definition vehicle.cpp:3325
@ 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 Commands::StartStopVehicle 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.
PoolID< uint32_t, struct VehicleIDTag, 0xFF000, 0xFFFFF > VehicleID
The type all our vehicle IDs have.
VehicleType
Available vehicle types.
@ Ship
Ship vehicle type.
@ Begin
Begin marker.
@ Invalid
Non-existing type of vehicle.
@ CompanyEnd
Last company-ownable type.
@ Aircraft
Aircraft vehicle type.
@ Road
Road vehicle type.
@ Train
Train vehicle type.
EnumIndexArray< T, VehicleType, Tend > VehicleTypeIndexArray
Array with VehicleType as index.
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:41
@ WWT_PUSHIMGBTN
Normal push-button (no toggle button) with image caption.
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:66
@ WWT_TEXTBTN
(Toggle) Button with text
Definition widget_type.h:44
@ WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX).
Definition widget_type.h:57
@ WWT_MATRIX
Grid of rows and columns.
Definition widget_type.h:50
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX).
Definition widget_type.h:55
@ WWT_CAPTION
Window caption (window title between closebox and stickybox).
Definition widget_type.h:52
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition widget_type.h:76
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:68
@ WWT_CLOSEBOX
Close box (at top-left of a window).
Definition widget_type.h:60
@ NWID_HSCROLLBAR
Horizontal scrollbar.
Definition widget_type.h:75
@ WWT_RESIZEBOX
Resize box (normally at bottom-right of a window).
Definition widget_type.h:59
@ 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
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:71
@ 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:1209
Window * BringWindowToFrontById(WindowClass cls, WindowNumber number)
Find a window and make it the relative top-window on the screen.
Definition window.cpp:1293
SpecialMouseMode _special_mouse_mode
Mode of the mouse.
Definition window.cpp:96
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition window.cpp:1166
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:953
@ WSM_DRAGDROP
Drag&drop an object.
@ Automatic
Find a place automatically.
Definition window_gui.h:144
int WidgetID
Widget ID.
Definition window_type.h:21
EventState
State of handling an event.
@ ES_HANDLED
The passed event is handled.
@ ES_NOT_HANDLED
The passed event is not handled.
static constexpr WidgetID INVALID_WIDGET
An invalid widget index.
Definition window_type.h:24
@ WC_VEHICLE_DEPOT
Depot view; Window numbers:
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:51
@ 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