OpenTTD Source 20260721-master-g25ec12c62d
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),
87};
88
91 WindowPosition::Automatic, "depot_train", 362, 123,
92 WindowClass::VehicleDepot, WindowClass::None,
93 {},
95);
96
99 WindowPosition::Automatic, "depot_roadveh", 316, 97,
100 WindowClass::VehicleDepot, WindowClass::None,
101 {},
103);
104
107 WindowPosition::Automatic, "depot_ship", 306, 99,
108 WindowClass::VehicleDepot, WindowClass::None,
109 {},
111);
112
115 WindowPosition::Automatic, "depot_aircraft", 332, 99,
116 WindowClass::VehicleDepot, WindowClass::None,
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) {
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 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 > height) 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 /* Limit sprite height to limits based on original design height to prevent window size running away. */
204 int min_height = ScaleSpriteTrad(GetVehicleHeight(type));
205 int max_height = min_height + min_height / 2;
206
207 switch (image_type) {
209 _base_block_sizes_depot[type].height = Clamp(height, min_height, max_height);
210 _base_block_sizes_depot[type].extend_left = Clamp(max_extend_left, min_extend, max_extend);
211 _base_block_sizes_depot[type].extend_right = Clamp(max_extend_right, min_extend, max_extend);
212 break;
214 _base_block_sizes_purchase[type].height = Clamp(height, min_height, max_height);
215 _base_block_sizes_purchase[type].extend_left = Clamp(max_extend_left, min_extend, max_extend);
216 _base_block_sizes_purchase[type].extend_right = Clamp(max_extend_right, min_extend, max_extend);
217 break;
218
219 default: NOT_REACHED();
220 }
221}
222
228{
230 InitBlocksizeForVehicles(vt, EngineImageType::InDepot);
231 InitBlocksizeForVehicles(vt, EngineImageType::Purchase);
232 }
233
234 _consistent_train_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
235 bool first = true;
237 if (!e->IsEnabled()) continue;
238
239 uint w = TRAININFO_DEFAULT_VEHICLE_WIDTH;
240 if (e->GetGRF() != nullptr && IsCustomVehicleSpriteNum(e->VehInfo<RailVehicleInfo>().image_index)) {
241 w = e->GetGRF()->traininfo_vehicle_width;
242 if (w != VEHICLEINFO_FULL_VEHICLE_WIDTH) {
243 /* Hopeless.
244 * This is a NewGRF vehicle that uses TRAININFO_DEFAULT_VEHICLE_WIDTH.
245 * If the vehicles are shorter than 8/8 we have fractional lengths, which are not consistent after rounding.
246 */
248 break;
249 }
250 }
251
252 if (first) {
254 first = false;
255 } else if (w != _consistent_train_width) {
257 break;
258 }
259 }
260}
261
262static void DepotSellAllConfirmationCallback(Window *w, bool confirmed);
263const Sprite *GetAircraftSprite(EngineID engine);
264
265struct DepotWindow : Window {
266 VehicleID sel = VehicleID::Invalid();
267 VehicleID vehicle_over = VehicleID::Invalid();
269 bool generate_list = true;
270 bool check_unitnumber_digits = true;
272 VehicleList vehicle_list{};
273 VehicleList wagon_list{};
274 uint unitnumber_digits = 2;
275 uint num_columns = 1;
276 Scrollbar *hscroll = nullptr;
277 Scrollbar *vscroll = nullptr;
278 uint count_width = 0;
279 uint header_width = 0;
282 bool last_overlay_state = false;
283
284 DepotWindow(WindowDesc &desc, TileIndex tile, VehicleType type) : Window(desc)
285 {
286 assert(IsCompanyBuildableVehicleType(type)); // ensure that we make the call with a valid type
287
288 this->type = type;
289
290 this->CreateNestedTree();
291 this->hscroll = (this->type == VehicleType::Train ? this->GetScrollbar(WID_D_H_SCROLL) : nullptr);
292 this->vscroll = this->GetScrollbar(WID_D_V_SCROLL);
293 /* Don't show 'rename button' of aircraft hangar */
294 this->GetWidget<NWidgetStacked>(WID_D_SHOW_RENAME)->SetDisplayedPlane(type == VehicleType::Aircraft ? SZSP_NONE : 0);
295 /* Only train depots have a horizontal scrollbar and a 'sell chain' button */
296 if (type == VehicleType::Train) this->GetWidget<NWidgetCore>(WID_D_MATRIX)->SetMatrixDimension(1, 0 /* auto-scale */);
298 this->GetWidget<NWidgetStacked>(WID_D_SHOW_SELL_CHAIN)->SetDisplayedPlane(type == VehicleType::Train ? 0 : SZSP_NONE);
299 this->SetupWidgetData(type);
300 this->FinishInitNested(tile);
301
302 this->owner = GetTileOwner(tile);
304 }
305
306 void Close([[maybe_unused]] int data = 0) override
307 {
308 CloseWindowById(WindowClass::BuildVehicle, this->window_number);
309 CloseWindowById(GetWindowClassForVehicleType(this->type), VehicleListIdentifier(VehicleListType::Depot, this->type, this->owner, this->GetDestinationIndex()).ToWindowNumber(), false);
311 this->Window::Close();
312 }
313
320 uint CountDraggedLength(const Train *t) const
321 {
322 /* Nothing is selected to add. */
323 if (this->sel == VehicleID::Invalid()) return 0;
324
325 /* Test if the dragged selection applies to this train. */
326 bool add_dragged = false;
327 for (const Train *u = t; u != nullptr; u = u->Next()) {
328 if (u->index == this->sel) return 0; // Selection is part of this train, so doesn't increase its length.
329 if (u->index == this->vehicle_over) add_dragged = true;
330 }
331
332 if (!add_dragged) return 0;
333
334 /* Sum the length of the dragged selection. */
335 uint length = 0;
336 for (Train *u = Train::Get(this->sel); u != nullptr; u = _cursor.vehchain ? u->Next() : (u->HasArticulatedPart() ? u->GetNextArticulatedPart() : nullptr)) {
337 length += u->gcache.cached_veh_length;
338 }
339
340 return length;
341 }
342
348 void DrawVehicleInDepot(const Vehicle *v, const Rect &r) const
349 {
350 bool free_wagon = false;
351
352 bool rtl = _current_text_dir == TD_RTL;
353 Rect text = r.Shrink(RectPadding::zero, WidgetDimensions::scaled.matrix); /* Ract for text elements, horizontal is already applied. */
354 Rect image = r.Indent(this->header_width, rtl).Indent(this->count_width, !rtl); /* Rect for vehicle images */
355
356 switch (v->type) {
357 case VehicleType::Train: {
358 const Train *u = Train::From(v);
359 free_wagon = u->IsFreeWagon();
360
361 uint x_space = free_wagon ?
362 ScaleSpriteTrad(_consistent_train_width != 0 ? _consistent_train_width : TRAININFO_DEFAULT_VEHICLE_WIDTH) :
363 0;
364
365 DrawTrainImage(u, image.Indent(x_space, rtl), this->sel, EngineImageType::InDepot, free_wagon ? 0 : this->hscroll->GetPosition(), this->vehicle_over);
366
367 /* Length of consist in tiles with 1 fractional digit (rounded up) */
368 uint length = u->gcache.cached_total_length + this->CountDraggedLength(u);
369 Rect count = text.WithWidth(this->count_width - WidgetDimensions::scaled.hsep_normal, !rtl);
370 DrawString(count.left, count.right, count.bottom - GetCharacterHeight(FontSize::Small) + 1,
371 GetString(STR_JUST_DECIMAL, CeilDiv(length * 10, TILE_SIZE), 1),
372 TextColour::Black, AlignmentH::ForceRight, false, FontSize::Small); // Draw the counter
373 break;
374 }
375
376 case VehicleType::Road: DrawRoadVehImage(v, image, this->sel, EngineImageType::InDepot); break;
377 case VehicleType::Ship: DrawShipImage(v, image, this->sel, EngineImageType::InDepot); break;
378 case VehicleType::Aircraft: DrawAircraftImage(v, image, this->sel, EngineImageType::InDepot); break;
379 default: NOT_REACHED();
380 }
381
382 uint diff_x, diff_y;
383 if (v->IsGroundVehicle()) {
384 /* Arrange unitnumber and flag horizontally */
385 diff_x = this->flag_size.width + WidgetDimensions::scaled.hsep_normal;
386 diff_y = WidgetDimensions::scaled.matrix.top;
387 } else {
388 /* Arrange unitnumber and flag vertically */
389 diff_x = 0;
391 }
392
393 text = text.WithWidth(this->header_width - WidgetDimensions::scaled.hsep_normal, rtl).WithHeight(GetCharacterHeight(FontSize::Normal)).Indent(diff_x, rtl);
394 if (free_wagon) {
395 DrawString(text, STR_DEPOT_NO_ENGINE);
396 } else {
397 Rect flag = r.WithWidth(this->flag_size.width, rtl).WithHeight(this->flag_size.height).Translate(0, diff_y);
398 DrawSpriteIgnorePadding((v->vehstatus.Test(VehState::Stopped)) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, flag, {AlignmentH::Centre, AlignmentV::Middle});
399
401 }
402 }
403
404 void DrawWidget(const Rect &r, WidgetID widget) const override
405 {
406 if (widget != WID_D_MATRIX) return;
407
408 bool rtl = _current_text_dir == TD_RTL;
409
410 /* Set the row and number of boxes in each row based on the number of boxes drawn in the matrix */
412
413 /* Set up rect for each cell */
414 Rect ir = r.WithHeight(this->resize.step_height);
415 if (this->num_columns != 1) ir = ir.WithWidth(this->resize.step_width, rtl);
416 ir = ir.Shrink(WidgetDimensions::scaled.framerect, RectPadding::zero);
417
418 /* Draw vertical separators at whole tiles.
419 * This only works in two cases:
420 * - All vehicles use VEHICLEINFO_FULL_VEHICLE_WIDTH as reference width.
421 * - All vehicles are 8/8. This cannot be checked for NewGRF, so instead we check for "all vehicles are original vehicles".
422 */
423 if (this->type == VehicleType::Train && _consistent_train_width != 0) {
426 Rect image = ir.Indent(this->header_width, rtl).Indent(this->count_width, !rtl);
427 int first_line = w + (-this->hscroll->GetPosition()) % w;
428 if (rtl) {
429 for (int x = image.right - first_line; x >= image.left; x -= w) {
430 GfxDrawLine(x, r.top, x, r.bottom, col, ScaleGUITrad(1), ScaleGUITrad(3));
431 }
432 } else {
433 for (int x = image.left + first_line; x <= image.right; x += w) {
434 GfxDrawLine(x, r.top, x, r.bottom, col, ScaleGUITrad(1), ScaleGUITrad(3));
435 }
436 }
437 }
438
439 uint16_t rows_in_display = wid->current_y / wid->resize_y;
440
441 uint num = this->vscroll->GetPosition() * this->num_columns;
442 uint maxval = static_cast<uint>(std::min<size_t>(this->vehicle_list.size(), num + (rows_in_display * this->num_columns)));
443 for (; num < maxval; ir = ir.Translate(0, this->resize.step_height)) { // Draw the rows
444 Rect cell = ir; /* Keep track of horizontal cells */
445 for (uint i = 0; i < this->num_columns && num < maxval; i++, num++) {
446 /* Draw all vehicles in the current row */
447 const Vehicle *v = this->vehicle_list[num];
448 this->DrawVehicleInDepot(v, cell);
449 cell = cell.Translate(rtl ? -(int)this->resize.step_width : (int)this->resize.step_width, 0);
450 }
451 }
452
453 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)));
454
455 /* Draw the train wagons without an engine in front. */
456 for (; num < maxval; num++, ir = ir.Translate(0, this->resize.step_height)) {
457 const Vehicle *v = this->wagon_list[num - this->vehicle_list.size()];
458 this->DrawVehicleInDepot(v, ir);
459 }
460 }
461
462 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
463 {
464 if (widget == WID_D_CAPTION) return GetString(STR_DEPOT_CAPTION, this->type, this->GetDestinationIndex());
465
466 return this->Window::GetWidgetString(widget, stringid);
467 }
468
476
480 const Vehicle *vehicle = nullptr;
481 const Vehicle *wagon = nullptr;
482 };
483
491 {
492 this->RefreshVehicleList();
493
494 const NWidgetCore *matrix_widget = this->GetWidget<NWidgetCore>(WID_D_MATRIX);
495 /* Make X relative to widget. Y is left alone for GetScrolledRowFromWidget(). */
496 x -= matrix_widget->pos_x;
497 /* In case of RTL the widgets are swapped as a whole */
498 if (_current_text_dir == TD_RTL) x = matrix_widget->current_x - x;
499
500 uint xt = 0, xm = 0, ym = 0;
501 if (this->type == VehicleType::Train) {
502 xm = x;
503 } else {
504 xt = x / this->resize.step_width;
505 xm = x % this->resize.step_width;
506 if (xt >= this->num_columns) return {.action = DepotGUIAction::Error};
507 }
508 ym = (y - matrix_widget->pos_y) % this->resize.step_height;
509
510 int32_t row = this->vscroll->GetScrolledRowFromWidget(y, this, WID_D_MATRIX);
511 uint pos = (row * this->num_columns) + xt;
512
513 if (row == INT32_MAX || this->vehicle_list.size() + this->wagon_list.size() <= pos) {
514 /* Clicking on 'line' / 'block' without a vehicle */
515 if (this->type == VehicleType::Train) {
516 /* End the dragging */
517 return {.action = DepotGUIAction::DragVehicle};
518 } else {
519 return {.action = DepotGUIAction::Error}; // empty block, so no vehicle is selected
520 }
521 }
522
523 const Vehicle *vehicle;
524 bool is_wagon = false;
525 if (this->vehicle_list.size() > pos) {
526 vehicle = this->vehicle_list[pos];
527 /* Skip vehicles that are scrolled off the list */
528 if (this->type == VehicleType::Train) x += this->hscroll->GetPosition();
529 } else {
530 pos -= (uint)this->vehicle_list.size();
531 vehicle = this->wagon_list[pos];
532 /* free wagons don't have an initial loco. */
533 x -= ScaleSpriteTrad(VEHICLEINFO_FULL_VEHICLE_WIDTH);
534 is_wagon = true;
535 }
536
537 if (xm <= this->header_width) {
538 switch (this->type) {
540 if (is_wagon) return {.action = DepotGUIAction::Error};
541 [[fallthrough]];
542
544 if (xm <= this->flag_size.width) return {.action = DepotGUIAction::StartStop, .vehicle = vehicle};
545 break;
546
549 if (xm <= this->flag_size.width && ym >= (uint)(GetCharacterHeight(FontSize::Normal) + WidgetDimensions::scaled.vsep_normal)) return {.action = DepotGUIAction::StartStop, .vehicle = vehicle};
550 break;
551
552 default: NOT_REACHED();
553 }
554 return {.action = DepotGUIAction::ShowVehicle, .vehicle = vehicle};
555 }
556
557 if (this->type != VehicleType::Train) return {.action = DepotGUIAction::DragVehicle, .vehicle = vehicle};
558
559 /* Clicking on the counter */
560 if (xm >= matrix_widget->current_x - this->count_width) {
561 if (is_wagon) return {.action = DepotGUIAction::Error};
562 return {.action = DepotGUIAction::ShowVehicle, .vehicle = vehicle};
563 }
564
565 /* Account for the header */
566 x -= this->header_width;
567
568 /* find the vehicle in this row that was clicked */
569 const Train *wagon = Train::From(vehicle);
570 for (; wagon != nullptr; wagon = wagon->Next()) {
571 x -= wagon->GetDisplayImageWidth();
572 if (x < 0) break;
573 }
574
575 return {.action = DepotGUIAction::DragVehicle, .vehicle = vehicle, .wagon = wagon != nullptr ? wagon->GetFirstEnginePart() : nullptr};
576 }
577
583 void DepotClick(int x, int y)
584 {
585 DepotActionResult result = this->GetVehicleFromDepotWndPt(x, y);
586 switch (result.action) {
587 case DepotGUIAction::Error: // invalid
588 return;
589
590 case DepotGUIAction::DragVehicle: { // start dragging of vehicle
591 const Vehicle *v = (this->type == VehicleType::Train) ? result.wagon : result.vehicle;
592
593 if (v != nullptr && VehicleClicked(v)) return;
594
595 VehicleID sel = this->sel;
596
597 if (this->type == VehicleType::Train && sel != VehicleID::Invalid()) {
598 this->sel = VehicleID::Invalid();
599 TrainDepotMoveVehicle(v, sel, result.vehicle);
600 } else if (v != nullptr) {
603 _cursor.vehchain = _ctrl_pressed;
604
605 this->sel = v->index;
606 this->SetDirty();
607 }
608 break;
609 }
610
611 case DepotGUIAction::ShowVehicle: // show info window
613 break;
614
615 case DepotGUIAction::StartStop: // click start/stop flag
616 StartStopVehicle(result.vehicle, false);
617 break;
618
619 default: NOT_REACHED();
620 }
621 }
622
631 {
632 this->GetWidget<NWidgetCore>(WID_D_STOP_ALL)->SetToolTip(STR_DEPOT_MASS_STOP_DEPOT_TRAIN_TOOLTIP + to_underlying(type));
633 this->GetWidget<NWidgetCore>(WID_D_START_ALL)->SetToolTip(STR_DEPOT_MASS_START_DEPOT_TRAIN_TOOLTIP + to_underlying(type));
634 this->GetWidget<NWidgetCore>(WID_D_SELL)->SetToolTip(STR_DEPOT_TRAIN_SELL_TOOLTIP + to_underlying(type));
635 this->GetWidget<NWidgetCore>(WID_D_SELL_ALL)->SetToolTip(STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TOOLTIP + to_underlying(type));
636
637 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));
638 this->GetWidget<NWidgetCore>(WID_D_CLONE)->SetStringTip(STR_DEPOT_CLONE_TRAIN + to_underlying(type), STR_DEPOT_CLONE_TRAIN_DEPOT_TOOLTIP + to_underlying(type));
639
640 this->GetWidget<NWidgetCore>(WID_D_LOCATION)->SetToolTip(STR_DEPOT_TRAIN_LOCATION_TOOLTIP + to_underlying(type));
641 this->GetWidget<NWidgetCore>(WID_D_VEHICLE_LIST)->SetToolTip(STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TOOLTIP + to_underlying(type));
642 this->GetWidget<NWidgetCore>(WID_D_AUTOREPLACE)->SetToolTip(STR_DEPOT_AUTOREPLACE_TRAIN_TOOLTIP + to_underlying(type));
643 this->GetWidget<NWidgetCore>(WID_D_MATRIX)->SetToolTip(STR_DEPOT_TRAIN_LIST_TOOLTIP + to_underlying(type));
644
645 switch (type) {
646 default: NOT_REACHED();
647
649 this->GetWidget<NWidgetCore>(WID_D_VEHICLE_LIST)->SetString(STR_TRAIN);
650
651 /* Sprites */
652 this->GetWidget<NWidgetCore>(WID_D_SELL)->SetSprite(SPR_SELL_TRAIN);
653 this->GetWidget<NWidgetCore>(WID_D_SELL_ALL)->SetSprite(SPR_SELL_ALL_TRAIN);
654 this->GetWidget<NWidgetCore>(WID_D_AUTOREPLACE)->SetSprite(SPR_REPLACE_TRAIN);
655 break;
656
658 this->GetWidget<NWidgetCore>(WID_D_VEHICLE_LIST)->SetString(STR_LORRY);
659
660 /* Sprites */
661 this->GetWidget<NWidgetCore>(WID_D_SELL)->SetSprite(SPR_SELL_ROADVEH);
662 this->GetWidget<NWidgetCore>(WID_D_SELL_ALL)->SetSprite(SPR_SELL_ALL_ROADVEH);
663 this->GetWidget<NWidgetCore>(WID_D_AUTOREPLACE)->SetSprite(SPR_REPLACE_ROADVEH);
664 break;
665
667 this->GetWidget<NWidgetCore>(WID_D_VEHICLE_LIST)->SetString(STR_SHIP);
668
669 /* Sprites */
670 this->GetWidget<NWidgetCore>(WID_D_SELL)->SetSprite(SPR_SELL_SHIP);
671 this->GetWidget<NWidgetCore>(WID_D_SELL_ALL)->SetSprite(SPR_SELL_ALL_SHIP);
672 this->GetWidget<NWidgetCore>(WID_D_AUTOREPLACE)->SetSprite(SPR_REPLACE_SHIP);
673 break;
674
676 this->GetWidget<NWidgetCore>(WID_D_VEHICLE_LIST)->SetString(STR_PLANE);
677
678 /* Sprites */
679 this->GetWidget<NWidgetCore>(WID_D_SELL)->SetSprite(SPR_SELL_AIRCRAFT);
680 this->GetWidget<NWidgetCore>(WID_D_SELL_ALL)->SetSprite(SPR_SELL_ALL_AIRCRAFT);
681 this->GetWidget<NWidgetCore>(WID_D_AUTOREPLACE)->SetSprite(SPR_REPLACE_AIRCRAFT);
682 break;
683 }
684 }
685
686 void OnInit() override
687 {
688 this->cell_size = GetVehicleImageCellSize(this->type, EngineImageType::InDepot);
690 }
691
692 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
693 {
694 switch (widget) {
695 case WID_D_MATRIX: {
696 uint min_height = 0;
697
698 if (this->type == VehicleType::Train) {
699 this->count_width = GetStringBoundingBox(GetString(STR_JUST_DECIMAL, GetParamMaxValue(1000, 0, FontSize::Small), 1), FontSize::Small).width + WidgetDimensions::scaled.hsep_normal;
700 } else {
701 this->count_width = 0;
702 }
703
704 Dimension unumber = GetStringBoundingBox(GetString(STR_JUST_COMMA, GetParamMaxDigits(this->unitnumber_digits)));
705
706 if (this->type == VehicleType::Train || this->type == VehicleType::Road) {
707 min_height = std::max<uint>(unumber.height, this->flag_size.height);
708 this->header_width = unumber.width + WidgetDimensions::scaled.hsep_normal + this->flag_size.width + WidgetDimensions::scaled.hsep_normal;
709 } else {
710 min_height = unumber.height + WidgetDimensions::scaled.vsep_normal + this->flag_size.height;
711 this->header_width = std::max<uint>(unumber.width, this->flag_size.width) + WidgetDimensions::scaled.hsep_normal;
712 }
713 int base_width = this->count_width + this->header_width + padding.width;
714
715 resize.height = std::max<uint>(this->cell_size.height, min_height + padding.height);
716 if (this->type == VehicleType::Train) {
717 resize.width = 1;
718 size.width = base_width + 2 * ScaleSpriteTrad(29); // about 2 parts
719 size.height = resize.height * 6;
720 } else {
721 resize.width = base_width + this->cell_size.extend_left + this->cell_size.extend_right;
722 size.width = resize.width * (this->type == VehicleType::Road ? 5 : 3);
723 size.height = resize.height * (this->type == VehicleType::Road ? 5 : 3);
724 }
725 fill.width = resize.width;
726 fill.height = resize.height;
727 break;
728 }
729 }
730 }
731
737 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
738 {
739 this->generate_list = true;
740 }
741
742 void RefreshVehicleList()
743 {
744 if (this->generate_list) {
745 /* Generate the vehicle list
746 * It's ok to use the wagon pointers for non-trains as they will be ignored */
747 BuildDepotVehicleList(this->type, TileIndex(this->window_number), &this->vehicle_list, &this->wagon_list);
748 this->generate_list = false;
749 DepotSortList(&this->vehicle_list);
750
751 this->check_unitnumber_digits = true;
752 }
753 }
754
755 void OnPaint() override
756 {
757 this->RefreshVehicleList();
758
759 if (this->check_unitnumber_digits) {
760 this->check_unitnumber_digits = false;
761 uint new_unitnumber_digits = GetUnitNumberDigits(this->vehicle_list);
762 /* Only increase the size; do not decrease to prevent constant changes */
763 if (this->unitnumber_digits < new_unitnumber_digits) {
764 this->unitnumber_digits = new_unitnumber_digits;
765 this->ReInit();
766 }
767 }
768
769 /* determine amount of items for scroller */
770 if (this->type == VehicleType::Train) {
771 uint max_width = ScaleSpriteTrad(VEHICLEINFO_FULL_VEHICLE_WIDTH);
772 for (uint num = 0; num < this->vehicle_list.size(); num++) {
773 uint width = 0;
774 for (const Train *v = Train::From(this->vehicle_list[num]); v != nullptr; v = v->Next()) {
775 width += v->GetDisplayImageWidth();
776 }
777 max_width = std::max(max_width, width);
778 }
779 /* Always have 1 empty row, so people can change the setting of the train */
780 this->vscroll->SetCount(this->vehicle_list.size() + this->wagon_list.size() + 1);
781 /* 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 */
782 this->hscroll->SetCount(max_width + ScaleSpriteTrad(2 * VEHICLEINFO_FULL_VEHICLE_WIDTH + 1));
783 } else {
784 this->vscroll->SetCount(CeilDiv((uint)this->vehicle_list.size(), this->num_columns));
785 }
786
787 /* Setup disabled buttons. */
788 TileIndex tile(this->window_number);
799
800 this->DrawWidgets();
801 }
802
803 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
804 {
805 switch (widget) {
806 case WID_D_MATRIX: // List
807 this->DepotClick(pt.x, pt.y);
808 break;
809
810 case WID_D_BUILD: // Build vehicle
812 ShowBuildVehicleWindow(TileIndex(this->window_number), this->type);
813 break;
814
815 case WID_D_CLONE: // Clone button
818
819 if (this->IsWidgetLowered(WID_D_CLONE)) {
820 static constexpr VehicleTypeIndexArray<const CursorID> clone_icons = {
823 };
824
825 SetObjectToPlaceWnd(clone_icons[this->type], PAL_NONE, HT_VEHICLE, this);
826 } else {
828 }
829 SndClickBeep();
830 break;
831
832 case WID_D_LOCATION:
833 if (_ctrl_pressed) {
835 } else {
837 }
838 break;
839
840 case WID_D_RENAME: // Rename button
841 ShowQueryString(GetString(STR_DEPOT_NAME, this->type, Depot::GetByTile(TileIndex(this->window_number))->index), STR_DEPOT_RENAME_DEPOT_CAPTION,
843 break;
844
845 case WID_D_STOP_ALL:
846 case WID_D_START_ALL: {
847 VehicleListIdentifier vli(VehicleListType::Depot, this->type, this->owner);
848 Command<Commands::MassStartStop>::Post(TileIndex(this->window_number), widget == WID_D_START_ALL, false, vli);
849 break;
850 }
851
852 case WID_D_SELL_ALL:
853 /* Only open the confirmation window if there are anything to sell */
854 if (!this->vehicle_list.empty() || !this->wagon_list.empty()) {
855 ShowQuery(
856 GetEncodedString(STR_DEPOT_CAPTION, this->type, this->GetDestinationIndex()),
857 GetEncodedString(STR_DEPOT_SELL_CONFIRMATION_TEXT),
858 this,
859 DepotSellAllConfirmationCallback
860 );
861 }
862 break;
863
865 ShowVehicleListWindow(GetTileOwner(this->window_number), this->type, TileIndex(this->window_number));
866 break;
867
869 Command<Commands::DepotMassAutoreplace>::Post(GetCmdAutoreplaceVehMsg(this->type), TileIndex(this->window_number), this->type);
870 break;
871
872 }
873 }
874
875 void OnQueryTextFinished(std::optional<std::string> str) override
876 {
877 if (!str.has_value()) return;
878
879 /* Do depot renaming */
880 Command<Commands::RenameDepot>::Post(STR_ERROR_CAN_T_RENAME_DEPOT, this->GetDestinationIndex().ToDepotID(), *str);
881 }
882
883 bool OnRightClick([[maybe_unused]] Point pt, WidgetID widget) override
884 {
885 if (widget != WID_D_MATRIX) return false;
886
887 DepotActionResult result = this->GetVehicleFromDepotWndPt(pt.x, pt.y);
888 const Vehicle *v = this->type == VehicleType::Train ? result.wagon : result.vehicle;
889 if (result.action != DepotGUIAction::DragVehicle || v == nullptr) return false;
890
891 CargoArray capacity{}, loaded{};
892
893 /* Display info for single (articulated) vehicle, or for whole chain starting with selected vehicle */
894 bool whole_chain = (this->type == VehicleType::Train && _ctrl_pressed);
895
896 /* loop through vehicle chain and collect cargoes */
897 uint num = 0;
898 for (const Vehicle *w = v; w != nullptr; w = w->Next()) {
899 if (w->cargo_cap > 0 && w->cargo_type < NUM_CARGO) {
900 capacity[w->cargo_type] += w->cargo_cap;
901 loaded [w->cargo_type] += w->cargo.StoredCount();
902 }
903
904 if (w->type == VehicleType::Train && !w->HasArticulatedPart()) {
905 num++;
906 if (!whole_chain) break;
907 }
908 }
909
910 /* Build tooltipstring */
911 static std::string details;
912 details.clear();
913
914 for (const CargoSpec *cs : _sorted_cargo_specs) {
915 CargoType cargo_type = cs->Index();
916 if (capacity[cargo_type] == 0) continue;
917
918 auto params = MakeParameters(cargo_type, loaded[cargo_type], cargo_type, capacity[cargo_type]);
919 AppendStringWithArgsInPlace(details, STR_DEPOT_VEHICLE_TOOLTIP_CARGO, params);
920 }
921
922 /* Show tooltip window */
923 if (whole_chain) {
924 GuiShowTooltips(this, GetEncodedString(STR_DEPOT_VEHICLE_TOOLTIP_CHAIN, num, details), TooltipCloseCondition::RightClick);
925 } else {
926 GuiShowTooltips(this, GetEncodedString(STR_DEPOT_VEHICLE_TOOLTIP, v->engine_type, details), TooltipCloseCondition::RightClick);
927 }
928
929 return true;
930 }
931
937 bool OnVehicleSelect(const Vehicle *v) override
938 {
939 if (_ctrl_pressed) {
940 /* Share-clone, do not open new viewport, and keep tool active */
941 Command<Commands::CloneVehicle>::Post(STR_ERROR_CAN_T_BUY_TRAIN + to_underlying(v->type), TileIndex(this->window_number), v->index, true);
942 } else {
943 /* Copy-clone, open viewport for new vehicle, and deselect the tool (assume player wants to change things on new vehicle) */
944 if (Command<Commands::CloneVehicle>::Post(STR_ERROR_CAN_T_BUY_TRAIN + to_underlying(v->type), CcCloneVehicle, TileIndex(this->window_number), v->index, false)) {
946 }
947 }
948
949 return true;
950 }
951
960 bool OnVehicleSelect(VehicleList::const_iterator begin, VehicleList::const_iterator end) override
961 {
962 if (!_ctrl_pressed) {
963 /* If CTRL is not pressed: If all the vehicles in this list have the same orders, then copy orders */
964 if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
965 return VehiclesHaveSameEngineList(v1, v2);
966 })) {
967 if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
968 return VehiclesHaveSameOrderList(v1, v2);
969 })) {
970 OnVehicleSelect(*begin);
971 } else {
972 ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_BUY_TRAIN + to_underlying((*begin)->type)),
973 GetEncodedString(STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST), WarningLevel::Info);
974 }
975 } else {
976 ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_BUY_TRAIN + to_underlying((*begin)->type)),
977 GetEncodedString(STR_ERROR_CAN_T_CLONE_VEHICLE_LIST), WarningLevel::Info);
978 }
979 } else {
980 /* If CTRL is pressed: If all the vehicles in this list share orders, then copy orders */
981 if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
982 return VehiclesHaveSameEngineList(v1, v2);
983 })) {
984 if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
985 return v1->FirstShared() == v2->FirstShared();
986 })) {
987 OnVehicleSelect(*begin);
988 } else {
989 ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_BUY_TRAIN + to_underlying((*begin)->type)),
990 GetEncodedString(STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST), WarningLevel::Info);
991 }
992 } else {
993 ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_BUY_TRAIN + to_underlying((*begin)->type)),
994 GetEncodedString(STR_ERROR_CAN_T_CLONE_VEHICLE_LIST), WarningLevel::Info);
995 }
996 }
997
998 return true;
999 }
1000
1001 void OnPlaceObjectAbort() override
1002 {
1003 /* abort clone */
1004 this->RaiseWidget(WID_D_CLONE);
1006
1007 /* abort drag & drop */
1008 this->sel = VehicleID::Invalid();
1009 this->vehicle_over = VehicleID::Invalid();
1011
1012 if (this->hovered_widget != INVALID_WIDGET) {
1013 this->SetWidgetLoweredState(this->hovered_widget, false);
1014 this->SetWidgetDirty(this->hovered_widget);
1015 this->hovered_widget = INVALID_WIDGET;
1016 }
1017 }
1018
1019 void OnMouseLoop() override
1020 {
1021 if (last_overlay_state != ShowCargoIconOverlay()) {
1022 last_overlay_state = ShowCargoIconOverlay();
1023 this->SetDirty();
1024 }
1025 }
1026
1027 void OnMouseDrag(Point pt, WidgetID widget) override
1028 {
1029 if (this->sel == VehicleID::Invalid()) return;
1030 if (widget != this->hovered_widget) {
1031 if (this->hovered_widget == WID_D_SELL || this->hovered_widget == WID_D_SELL_CHAIN) {
1032 this->SetWidgetLoweredState(this->hovered_widget, false);
1033 this->SetWidgetDirty(this->hovered_widget);
1034 }
1035 this->hovered_widget = widget;
1036 if (this->hovered_widget == WID_D_SELL || this->hovered_widget == WID_D_SELL_CHAIN) {
1037 this->SetWidgetLoweredState(this->hovered_widget, true);
1038 this->SetWidgetDirty(this->hovered_widget);
1039 }
1040 }
1041 if (this->type != VehicleType::Train) return;
1042
1043 /* A rail vehicle is dragged.. */
1044 if (widget != WID_D_MATRIX) { // ..outside of the depot matrix.
1045 if (this->vehicle_over != VehicleID::Invalid()) {
1046 this->vehicle_over = VehicleID::Invalid();
1048 }
1049 return;
1050 }
1051
1052 DepotActionResult result = this->GetVehicleFromDepotWndPt(pt.x, pt.y);
1053 if (result.action != DepotGUIAction::DragVehicle) return;
1054
1055 VehicleID new_vehicle_over = VehicleID::Invalid();
1056 if (result.vehicle != nullptr) {
1057 if (result.wagon == nullptr && result.vehicle->Last()->index != this->sel) { // ..at the end of the train.
1058 /* 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
1059 * destination inside a train. This head index is then used to indicate that a wagon is inserted at
1060 * the end of the train.
1061 */
1062 new_vehicle_over = result.vehicle->index;
1063 } else if (result.wagon != nullptr && result.vehicle != result.wagon &&
1064 result.wagon->index != this->sel &&
1065 result.wagon->Previous()->index != this->sel) { // ..over an existing wagon.
1066 new_vehicle_over = result.wagon->index;
1067 }
1068 }
1069
1070 if (this->vehicle_over == new_vehicle_over) return;
1071
1072 this->vehicle_over = new_vehicle_over;
1073 this->SetWidgetDirty(widget);
1074 }
1075
1076 void OnDragDrop(Point pt, WidgetID widget) override
1077 {
1078 switch (widget) {
1079 case WID_D_MATRIX: {
1080 DepotActionResult result = this->GetVehicleFromDepotWndPt(pt.x, pt.y);
1081 VehicleID sel = this->sel;
1082
1083 this->sel = VehicleID::Invalid();
1084 this->SetDirty();
1085
1086 if (this->type == VehicleType::Train) {
1087 if (result.action == DepotGUIAction::DragVehicle && sel != VehicleID::Invalid()) {
1088 if (result.wagon != nullptr && result.wagon->index == sel && _ctrl_pressed) {
1089 Command<Commands::ReverseTrainDirection>::Post(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE, Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true);
1090 } else if (result.wagon == nullptr || result.wagon->index != sel) {
1091 this->vehicle_over = VehicleID::Invalid();
1092 TrainDepotMoveVehicle(result.wagon, sel, result.vehicle);
1093 } else if (result.vehicle != nullptr && result.vehicle->IsFrontEngine()) {
1095 }
1096 }
1097 } else if (result.action == DepotGUIAction::DragVehicle && result.vehicle != nullptr && sel == result.vehicle->index) {
1099 }
1100 break;
1101 }
1102
1103 case WID_D_SELL: case WID_D_SELL_CHAIN: {
1104 if (this->IsWidgetDisabled(widget)) return;
1105 if (this->sel == VehicleID::Invalid()) return;
1106
1107 this->HandleButtonClick(widget);
1108
1109 const Vehicle *v = Vehicle::Get(this->sel);
1110 this->sel = VehicleID::Invalid();
1111 this->SetDirty();
1112
1113 bool sell_cmd = (v->type == VehicleType::Train && (widget == WID_D_SELL_CHAIN || _ctrl_pressed));
1114 Command<Commands::SellVehicle>::Post(GetCmdSellVehMsg(v->type), v->tile, v->index, sell_cmd, true, ClientID::Invalid);
1115 break;
1116 }
1117
1118 default:
1119 this->sel = VehicleID::Invalid();
1120 this->SetDirty();
1121 break;
1122 }
1123 this->hovered_widget = INVALID_WIDGET;
1124 _cursor.vehchain = false;
1125 }
1126
1127 void OnTimeout() override
1128 {
1129 if (!this->IsWidgetDisabled(WID_D_SELL)) {
1130 this->RaiseWidget(WID_D_SELL);
1132 }
1133 if (this->GetWidget<NWidgetBase>(WID_D_SELL) != nullptr && !this->IsWidgetDisabled(WID_D_SELL_CHAIN)) {
1136 }
1137 }
1138
1139 void OnResize() override
1140 {
1141 this->vscroll->SetCapacityFromWidget(this, WID_D_MATRIX);
1143 if (this->type == VehicleType::Train) {
1144 this->hscroll->SetCapacity(nwi->current_x - this->header_width - this->count_width);
1145 } else {
1146 this->num_columns = nwi->current_x / nwi->resize_x;
1147 }
1148 }
1149
1151 {
1152 if (this->sel != VehicleID::Invalid()) {
1153 _cursor.vehchain = _ctrl_pressed;
1155 return EventState::Handled;
1156 }
1157
1159 }
1160
1167 {
1169 }
1170};
1171
1172static void DepotSellAllConfirmationCallback(Window *win, bool confirmed)
1173{
1174 if (confirmed) {
1175 DepotWindow *w = (DepotWindow*)win;
1176 TileIndex tile(w->window_number);
1177 VehicleType vehtype = w->type;
1178 Command<Commands::DepotMassSell>::Post(GetCmdSellAllVehMsg(vehtype), tile, vehtype);
1179 }
1180}
1181
1188{
1189 if (BringWindowToFrontById(WindowClass::VehicleDepot, tile) != nullptr) return;
1190
1191 switch (type) {
1192 default: NOT_REACHED();
1193 case VehicleType::Train: new DepotWindow(_train_depot_desc, tile, type); break;
1194 case VehicleType::Road: new DepotWindow(_road_depot_desc, tile, type); break;
1195 case VehicleType::Ship: new DepotWindow(_ship_depot_desc, tile, type); break;
1196 case VehicleType::Aircraft: new DepotWindow(_aircraft_depot_desc, tile, type); break;
1197 }
1198}
1199
1205{
1206 DepotWindow *w;
1207
1208 /* If we haven't got any vehicles on the mouse pointer, we haven't got any highlighted in any depots either
1209 * If that is the case, we can skip looping though the windows and save time
1210 */
1212
1213 w = dynamic_cast<DepotWindow*>(FindWindowById(WindowClass::VehicleDepot, v->tile));
1214 if (w != nullptr) {
1215 if (w->sel == v->index) ResetObjectToPlace();
1216 }
1217}
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.
Iterate a range of enum values.
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:2462
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:2536
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 uint _consistent_train_width
Whether trains of all lengths are consistently scaled. Either TRAININFO_DEFAULT_VEHICLE_WIDTH,...
static WindowDesc _train_depot_desc(WindowPosition::Automatic, "depot_train", 362, 123, WindowClass::VehicleDepot, WindowClass::None, {}, _nested_train_depot_widgets)
Window definition for the train depot window.
static WindowDesc _road_depot_desc(WindowPosition::Automatic, "depot_roadveh", 316, 97, WindowClass::VehicleDepot, WindowClass::None, {}, _nested_train_depot_widgets)
Window definition for the road depot window.
static WindowDesc _ship_depot_desc(WindowPosition::Automatic, "depot_ship", 306, 99, WindowClass::VehicleDepot, WindowClass::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, WindowClass::VehicleDepot, WindowClass::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.
@ 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.
@ ForceRight
Force align to the right.
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:899
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:39
int DrawString(int left, int right, int top, std::string_view str, ExtendedTextColour colour, Alignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition gfx.cpp:668
Dimension GetScaledSpriteSize(SpriteID sprid)
Scale sprite size for GUI.
Definition widget.cpp:70
void DrawSpriteIgnorePadding(SpriteID img, PaletteID pal, const Rect &r, Alignment align)
Draw a sprite within a Rect, ignoring the sprite's padding.
Definition widget.cpp:350
@ 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
@ Invalid
Invalid marker.
Definition gfx_type.h:302
@ Grey
Grey.
Definition gfx_type.h:299
@ Black
Black colour.
Definition gfx_type.h:334
@ Red
Red colour.
Definition gfx_type.h:321
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.
static const CursorID SPR_CURSOR_CLONE_AIRPLANE
Definition sprites.h:1666
static const CursorID SPR_CURSOR_CLONE_TRAIN
Definition sprites.h:1663
static const CursorID SPR_CURSOR_CLONE_ROADVEH
Definition sprites.h:1664
static const CursorID SPR_CURSOR_MOUSE
Definition sprites.h:1567
static const CursorID SPR_CURSOR_CLONE_SHIP
Definition sprites.h:1665
void SetDirty() const
Mark entire window as dirty (in need of re-paint).
Definition window.cpp:972
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 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:254
Functions related to sound.
Types related to the sprite cache.
static const SpriteID SPR_FLAG_VEH_STOPPED
Vehicle sprite-flags (red/green).
Definition sprites.h:1097
static const SpriteID SPR_FLAG_VEH_RUNNING
Vehicle sprite-flags (red/green).
Definition sprites.h:1098
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:118
Specification of a cargo type.
Definition cargotype.h:77
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:307
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:172
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:984
virtual void Close(int data=0)
Hide the window and all its child windows, and mark them for a later deletion.
Definition window.cpp:1109
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1814
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:792
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:562
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
Definition window.cpp:510
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:1804
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
Window(WindowDesc &desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
Definition window.cpp:1838
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:989
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:601
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition window.cpp:319
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)
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:3325
bool VehiclesHaveSameOrderList(const Vehicle *v1, const Vehicle *v2)
Checks if two vehicles have the same list of orders.
Definition vehicle.cpp:3342
@ 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.
@ InDepot
Vehicle drawn in depot.
@ Purchase
Vehicle drawn in purchase list, autoreplace gui, ...
PoolID< uint32_t, struct VehicleIDTag, 0xFF000, 0xFFFFF > VehicleID
The type all our vehicle IDs have.
VehicleType
Available vehicle types.
@ Ship
Ship vehicle type.
@ 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
@ Depot
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:1201
Window * BringWindowToFrontById(WindowClass cls, WindowNumber number)
Find a window and make it the relative top-window on the screen.
Definition window.cpp:1285
SpecialMouseMode _special_mouse_mode
Mode of the mouse.
Definition window.cpp:88
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition window.cpp:1158
Functions, definitions and such used only by the GUI.
@ RightClick
Close the tooltip when releasing the right mouse button.
Definition window_gui.h:264
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:952
@ DragDrop
Drag&drop an object.
@ Automatic
Find a place automatically.
Definition window_gui.h:146
int WidgetID
Widget ID.
Definition window_type.h:21
EventState
State of handling an event.
@ Handled
The passed event is handled.
@ NotHandled
The passed event is not handled.
static constexpr WidgetID INVALID_WIDGET
An invalid widget index.
Definition window_type.h:24
Functions related to zooming.
int ScaleSpriteTrad(int value)
Scale traditional pixel dimensions to GUI zoom level, for drawing sprites.
Definition zoom_func.h:107