OpenTTD Source 20250312-master-gcdcc6b491d
autoreplace_gui.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11#include "command_func.h"
12#include "vehicle_gui.h"
13#include "newgrf_badge.h"
14#include "newgrf_engine.h"
15#include "rail.h"
16#include "road.h"
17#include "strings_func.h"
18#include "window_func.h"
19#include "autoreplace_func.h"
20#include "company_func.h"
21#include "engine_base.h"
22#include "window_gui.h"
23#include "engine_gui.h"
24#include "settings_func.h"
26#include "rail_gui.h"
27#include "road_gui.h"
28#include "dropdown_type.h"
29#include "dropdown_func.h"
30#include "autoreplace_cmd.h"
31#include "group_cmd.h"
32#include "settings_cmd.h"
33
35
36#include "safeguards.h"
37
38static bool EngineNumberSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
39{
40 return Engine::Get(a.engine_id)->list_position < Engine::Get(b.engine_id)->list_position;
41}
42
53{
55 /* We don't have any of this engine type.
56 * Either we just sold the last one, we build a new one or we stopped replacing it.
57 * In all cases, we need to update the left list */
59 }
60}
61
67{
68 InvalidateWindowData(WC_REPLACE_VEHICLE, type, 0); // Update the autoreplace window
69 InvalidateWindowClassesData(WC_BUILD_VEHICLE); // The build windows needs updating as well
70}
71
72static const StringID _start_replace_dropdown[] = {
73 STR_REPLACE_VEHICLES_NOW,
74 STR_REPLACE_VEHICLES_WHEN_OLD,
75};
76
81 std::array<EngineID, 2> sel_engine{};
82 std::array<GUIEngineList, 2> engines{};
83 bool replace_engines = true;
84 bool reset_sel_engine = true;
85 GroupID sel_group = GroupID::Invalid();
89 bool descending_sort_order = false;
90 bool show_hidden_engines = false;
93 std::array<Scrollbar *, 2> vscroll{};
94 GUIBadgeClasses badge_classes{};
95
104 {
105 const RailVehicleInfo *rvi = RailVehInfo(e);
106
107 /* Ensure that the wagon/engine selection fits the engine. */
108 if ((rvi->railveh_type == RAILVEH_WAGON) == show_engines) return false;
109
110 if (draw_left && this->sel_railtype != INVALID_RAILTYPE) {
111 /* Ensure that the railtype is specific to the selected one */
112 if (rvi->railtype != this->sel_railtype) return false;
113 }
114 return true;
115 }
116
122 {
123 std::vector<EngineID> variants;
124 EngineID selected_engine = EngineID::Invalid();
125 VehicleType type = this->window_number;
126 uint8_t side = draw_left ? 0 : 1;
127
128 GUIEngineList list;
129
130 for (const Engine *e : Engine::IterateType(type)) {
131 if (!draw_left && !this->show_hidden_engines && e->IsVariantHidden(_local_company)) continue;
132 EngineID eid = e->index;
133 switch (type) {
134 case VEH_TRAIN:
135 if (!this->GenerateReplaceRailList(eid, draw_left, this->replace_engines)) continue; // special rules for trains
136 break;
137
138 case VEH_ROAD:
139 if (draw_left && this->sel_roadtype != INVALID_ROADTYPE) {
140 /* Ensure that the roadtype is specific to the selected one */
141 if (e->u.road.roadtype != this->sel_roadtype) continue;
142 }
143 break;
144
145 default:
146 break;
147 }
148
149 if (draw_left) {
150 const uint num_engines = GetGroupNumEngines(_local_company, this->sel_group, eid);
151
152 /* Skip drawing the engines we don't have any of and haven't set for replacement */
153 if (num_engines == 0 && EngineReplacementForCompany(Company::Get(_local_company), eid, this->sel_group) == EngineID::Invalid()) continue;
154 } else {
155 if (!CheckAutoreplaceValidity(this->sel_engine[0], eid, _local_company)) continue;
156 }
157
158 list.emplace_back(eid, e->info.variant_id, (side == 0) ? EngineDisplayFlags{} : e->display_flags, 0);
159
160 if (side == 1) {
161 EngineID parent = e->info.variant_id;
162 while (parent != EngineID::Invalid()) {
163 variants.push_back(parent);
164 parent = Engine::Get(parent)->info.variant_id;
165 }
166 }
167 if (eid == this->sel_engine[side]) selected_engine = eid; // The selected engine is still in the list
168 }
169
170 if (side == 1) {
171 /* ensure primary engine of variant group is in list */
172 for (const auto &variant : variants) {
173 if (std::ranges::find(list, variant, &GUIEngineListItem::engine_id) == list.end()) {
174 const Engine *e = Engine::Get(variant);
175 list.emplace_back(variant, e->info.variant_id, e->display_flags | EngineDisplayFlag::Shaded, 0);
176 }
177 }
178 }
179
180 this->sel_engine[side] = selected_engine; // update which engine we selected (the same or none, if it's not in the list anymore)
181 if (draw_left) {
182 EngList_Sort(list, &EngineNumberSorter);
183 } else {
185 EngList_Sort(list, _engine_sort_functions[this->window_number][this->sort_criteria]);
186 }
187
188 this->engines[side].clear();
189 if (side == 1) {
190 GUIEngineListAddChildren(this->engines[side], list);
191 } else {
192 this->engines[side].swap(list);
193 }
194 }
195
198 {
199 EngineID e = this->sel_engine[0];
200
201 if (this->engines[0].NeedRebuild()) {
202 /* We need to rebuild the left engines list */
203 this->GenerateReplaceVehList(true);
204 this->vscroll[0]->SetCount(this->engines[0].size());
205 if (this->reset_sel_engine && this->sel_engine[0] == EngineID::Invalid() && !this->engines[0].empty()) {
206 this->sel_engine[0] = this->engines[0][0].engine_id;
207 }
208 }
209
210 if (this->engines[1].NeedRebuild() || e != this->sel_engine[0]) {
211 /* Either we got a request to rebuild the right engines list, or the left engines list selected a different engine */
212 if (this->sel_engine[0] == EngineID::Invalid()) {
213 /* Always empty the right engines list when nothing is selected in the left engines list */
214 this->engines[1].clear();
215 this->sel_engine[1] = EngineID::Invalid();
216 this->vscroll[1]->SetCount(this->engines[1].size());
217 } else {
218 if (this->reset_sel_engine && this->sel_engine[0] != EngineID::Invalid()) {
219 /* Select the current replacement for sel_engine[0]. */
221 this->sel_engine[1] = EngineReplacementForCompany(c, this->sel_engine[0], this->sel_group);
222 }
223 /* Regenerate the list on the right. Note: This resets sel_engine[1] to EngineID::Invalid(), if it is no longer available. */
224 this->GenerateReplaceVehList(false);
225 this->vscroll[1]->SetCount(this->engines[1].size());
226 if (this->reset_sel_engine && this->sel_engine[1] != EngineID::Invalid()) {
227 int position = 0;
228 for (const auto &item : this->engines[1]) {
229 if (item.engine_id == this->sel_engine[1]) break;
230 ++position;
231 }
232 this->vscroll[1]->ScrollTowards(position);
233 }
234 }
235 }
236 /* Reset the flags about needed updates */
237 this->engines[0].RebuildDone();
238 this->engines[1].RebuildDone();
239 this->reset_sel_engine = false;
240 }
241
246 void ReplaceClick_StartReplace(bool replace_when_old)
247 {
248 EngineID veh_from = this->sel_engine[0];
249 EngineID veh_to = this->sel_engine[1];
250 Command<CMD_SET_AUTOREPLACE>::Post(this->sel_group, veh_from, veh_to, replace_when_old);
251 }
252
257 {
258 /* Reset scrollbar positions */
259 this->vscroll[0]->SetPosition(0);
260 this->vscroll[1]->SetPosition(0);
261 /* Rebuild the lists */
262 this->engines[0].ForceRebuild();
263 this->engines[1].ForceRebuild();
264 this->reset_sel_engine = true;
265 this->SetDirty();
266 }
267
268public:
270 {
271 this->vehicle_type = vehicletype;
272 this->engines[0].ForceRebuild();
273 this->engines[1].ForceRebuild();
274 this->details_height = ((vehicletype == VEH_TRAIN) ? 10 : 9);
275 this->sel_engine[0] = EngineID::Invalid();
276 this->sel_engine[1] = EngineID::Invalid();
277 this->show_hidden_engines = _engine_sort_show_hidden_engines[vehicletype];
278
279 this->CreateNestedTree();
280 this->vscroll[0] = this->GetScrollbar(WID_RV_LEFT_SCROLLBAR);
281 this->vscroll[1] = this->GetScrollbar(WID_RV_RIGHT_SCROLLBAR);
282
285 widget->SetLowered(this->show_hidden_engines);
286 this->FinishInitNested(vehicletype);
287
288 this->sort_criteria = _engine_sort_last_criteria[vehicletype];
289 this->descending_sort_order = _engine_sort_last_order[vehicletype];
290 this->owner = _local_company;
291 this->sel_group = id_g;
292 }
293
294 void OnInit() override
295 {
296 this->badge_classes = GUIBadgeClasses(static_cast<GrfSpecFeature>(GSF_TRAINS + this->vehicle_type));
297 }
298
300 {
301 switch (widget) {
304 d.width += padding.width + Window::SortButtonWidth() * 2; // Doubled since the string is centred and it also looks better.
305 d.height += padding.height;
306 size = maxdim(size, d);
307 break;
308 }
309
313 size.height = (this->window_number <= VEH_ROAD ? 8 : 4) * resize.height;
314 break;
315
318 size.height = GetCharacterHeight(FS_NORMAL) * this->details_height + padding.height;
319 break;
320
322 StringID str = this->GetWidget<NWidgetCore>(widget)->GetString();
326 d.width += padding.width;
327 d.height += padding.height;
328 size = maxdim(size, d);
329 break;
330 }
331
335 d.width += padding.width;
336 d.height += padding.height;
337 size = maxdim(size, d);
338 break;
339 }
340
341 case WID_RV_INFO_TAB: {
344 d.width += padding.width;
345 d.height += padding.height;
346 size = maxdim(size, d);
347 break;
348 }
349
351 Dimension d = {0, 0};
352 for (const RailType &rt : _sorted_railtypes) {
354 }
355 d.width += padding.width;
356 d.height += padding.height;
357 size = maxdim(size, d);
358 break;
359 }
360
362 Dimension d = {0, 0};
363 for (const RoadType &rt : _sorted_roadtypes) {
365 }
366 d.width += padding.width;
367 d.height += padding.height;
368 size = maxdim(size, d);
369 break;
370 }
371
374 d = maxdim(d, GetStringListBoundingBox(_start_replace_dropdown));
375 d.width += padding.width;
376 d.height += padding.height;
377 size = maxdim(size, d);
378 break;
379 }
380 }
381 }
382
383 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
384 {
385 switch (widget) {
386 case WID_RV_CAPTION:
387 switch (this->sel_group.base()) {
388 case ALL_GROUP.base():
390 break;
391
392 case DEFAULT_GROUP.base():
394 break;
395
396 default:
398 }
399 break;
400
402 return GetString(std::data(_engine_sort_listing[this->window_number])[this->sort_criteria]);
403
405 if (const Group *g = Group::GetIfValid(this->sel_group); g != nullptr) {
406 bool remove_wagon = g->flags.Test(GroupFlag::ReplaceWagonRemoval);
408 } else {
411 return GetString(STR_GROUP_DEFAULT_TRAINS + this->window_number, std::monostate{}, remove_wagon ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF);
412 }
413 break;
414
416 return GetString(this->replace_engines ? STR_REPLACE_ENGINES : STR_REPLACE_WAGONS);
417
419 return GetString(this->sel_railtype == INVALID_RAILTYPE ? STR_REPLACE_ALL_RAILTYPE : GetRailTypeInfo(this->sel_railtype)->strings.replace_text);
420
422 return GetString(this->sel_roadtype == INVALID_ROADTYPE ? STR_REPLACE_ALL_ROADTYPE : GetRoadTypeInfo(this->sel_roadtype)->strings.replace_text);
423
424 default:
425 return this->Window::GetWidgetString(widget, stringid);
426 }
427 }
428
429 void DrawWidget(const Rect &r, WidgetID widget) const override
430 {
431 switch (widget) {
433 this->DrawSortButtonState(WID_RV_SORT_ASCENDING_DESCENDING, this->descending_sort_order ? SBS_DOWN : SBS_UP);
434 break;
435
436 case WID_RV_INFO_TAB: {
438 std::string str;
439 if (this->sel_engine[0] != EngineID::Invalid()) {
440 if (!EngineHasReplacementForCompany(c, this->sel_engine[0], this->sel_group)) {
442 } else {
443 bool when_old = false;
444 EngineID e = EngineReplacementForCompany(c, this->sel_engine[0], this->sel_group, &when_old);
446 }
447 } else {
449 }
450
452 break;
453 }
454
456 case WID_RV_RIGHT_MATRIX: {
457 int side = (widget == WID_RV_LEFT_MATRIX) ? 0 : 1;
458
459 /* Do the actual drawing */
460 DrawEngineList(this->window_number, r, this->engines[side], *this->vscroll[side], this->sel_engine[side], side == 0, this->sel_group, this->badge_classes);
461 break;
462 }
463 }
464 }
465
466 void OnPaint() override
467 {
468 if (this->engines[0].NeedRebuild() || this->engines[1].NeedRebuild()) this->GenerateLists();
469
471
472 /* Disable the "Start Replacing" button if:
473 * Either engines list is empty
474 * or The selected replacement engine has a replacement (to prevent loops). */
476 this->sel_engine[0] == EngineID::Invalid() || this->sel_engine[1] == EngineID::Invalid() || EngineReplacementForCompany(c, this->sel_engine[1], this->sel_group) != EngineID::Invalid());
477
478 /* Disable the "Stop Replacing" button if:
479 * The left engines list (existing vehicle) is empty
480 * or The selected vehicle has no replacement set up */
481 this->SetWidgetDisabledState(WID_RV_STOP_REPLACE, this->sel_engine[0] == EngineID::Invalid() || !EngineHasReplacementForCompany(c, this->sel_engine[0], this->sel_group));
482
483 this->DrawWidgets();
484
485 if (!this->IsShaded()) {
486 int needed_height = this->details_height;
487 /* Draw details panels. */
488 for (int side = 0; side < 2; side++) {
489 if (this->sel_engine[side] != EngineID::Invalid()) {
490 /* Use default engine details without refitting */
491 const Engine *e = Engine::Get(this->sel_engine[side]);
493 ted.cost = 0;
494 ted.FillDefaultCapacities(e);
495
496 const Rect r = this->GetWidget<NWidgetBase>(side == 0 ? WID_RV_LEFT_DETAILS : WID_RV_RIGHT_DETAILS)->GetCurrentRect()
498 int text_end = DrawVehiclePurchaseInfo(r.left, r.right, r.top, this->sel_engine[side], ted);
500 }
501 }
502 if (needed_height != this->details_height) { // Details window are not high enough, enlarge them.
503 this->details_height = needed_height;
504 this->ReInit();
505 return;
506 }
507 }
508 }
509
510 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
511 {
512 switch (widget) {
514 this->descending_sort_order ^= true;
516 this->engines[1].ForceRebuild();
517 this->SetDirty();
518 break;
519
521 this->show_hidden_engines ^= true;
523 this->engines[1].ForceRebuild();
524 this->SetWidgetLoweredState(widget, this->show_hidden_engines);
525 this->SetDirty();
526 break;
527
529 DisplayVehicleSortDropDown(this, this->window_number, this->sort_criteria, WID_RV_SORT_DROPDOWN);
530 break;
531
533 DropDownList list;
534 list.push_back(MakeDropDownListStringItem(STR_REPLACE_ENGINES, 1));
535 list.push_back(MakeDropDownListStringItem(STR_REPLACE_WAGONS, 0));
536 ShowDropDownList(this, std::move(list), this->replace_engines ? 1 : 0, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN);
537 break;
538 }
539
540 case WID_RV_RAIL_TYPE_DROPDOWN: // Railtype selection dropdown menu
541 ShowDropDownList(this, GetRailTypeDropDownList(true, true), this->sel_railtype, widget);
542 break;
543
544 case WID_RV_ROAD_TYPE_DROPDOWN: // Roadtype selection dropdown menu
545 ShowDropDownList(this, GetRoadTypeDropDownList(RTTB_ROAD | RTTB_TRAM, true, true), this->sel_roadtype, widget);
546 break;
547
549 const Group *g = Group::GetIfValid(this->sel_group);
550 if (g != nullptr) {
552 } else {
553 // toggle renew_keep_length
554 Command<CMD_CHANGE_COMPANY_SETTING>::Post("company.renew_keep_length", Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1);
555 }
556 break;
557 }
558
559 case WID_RV_START_REPLACE: { // Start replacing
560 if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
563 } else {
565 ShowDropDownMenu(this, _start_replace_dropdown, replacment_when_old ? 1 : 0, WID_RV_START_REPLACE, !this->replace_engines ? 1 << 1 : 0, 0);
566 }
567 break;
568 }
569
570 case WID_RV_STOP_REPLACE: { // Stop replacing
571 EngineID veh_from = this->sel_engine[0];
572 Command<CMD_SET_AUTOREPLACE>::Post(this->sel_group, veh_from, EngineID::Invalid(), false);
573 break;
574 }
575
577 case WID_RV_RIGHT_MATRIX: {
579 if (widget == WID_RV_LEFT_MATRIX) {
580 click_side = 0;
581 } else {
582 click_side = 1;
583 }
584
585 EngineID e = EngineID::Invalid();
586 const auto it = this->vscroll[click_side]->GetScrolledItemFromWidget(this->engines[click_side], pt.y, this, widget);
587 if (it != this->engines[click_side].end()) {
588 const auto &item = *it;
589 const Rect r = this->GetWidget<NWidgetBase>(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.matrix).WithWidth(WidgetDimensions::scaled.hsep_indent * (item.indent + 1), _current_text_dir == TD_RTL);
590 if (item.flags.Test(EngineDisplayFlag::HasVariants) && IsInsideMM(r.left, r.right, pt.x)) {
591 /* toggle folded flag on engine */
592 assert(item.variant_id != EngineID::Invalid());
593 Engine *engine = Engine::Get(item.variant_id);
595
596 InvalidateWindowData(WC_REPLACE_VEHICLE, this->window_number, 0); // Update the autoreplace window
597 InvalidateWindowClassesData(WC_BUILD_VEHICLE); // The build windows needs updating as well
598 return;
599 }
600 if (!item.flags.Test(EngineDisplayFlag::Shaded)) e = item.engine_id;
601 }
602
603 /* If Ctrl is pressed on the left side and we don't have any engines of the selected type, stop autoreplacing.
604 * This is most common when we have finished autoreplacing the engine and want to remove it from the list. */
605 if (click_side == 0 && _ctrl_pressed && e != EngineID::Invalid() &&
608 Command<CMD_SET_AUTOREPLACE>::Post(this->sel_group, veh_from, EngineID::Invalid(), false);
609 break;
610 }
611
612 if (e == this->sel_engine[click_side]) break; // we clicked the one we already selected
613 this->sel_engine[click_side] = e;
614 if (click_side == 0) {
615 this->engines[1].ForceRebuild();
616 this->reset_sel_engine = true;
617 }
618 this->SetDirty();
619 break;
620 }
621 }
622 }
623
624 void OnDropdownSelect(WidgetID widget, int index) override
625 {
626 switch (widget) {
628 if (this->sort_criteria != index) {
629 this->sort_criteria = index;
631 this->engines[1].ForceRebuild();
632 this->SetDirty();
633 }
634 break;
635
637 RailType temp = (RailType)index;
638 if (temp == this->sel_railtype) return; // we didn't select a new one. No need to change anything
639 this->sel_railtype = temp;
640 this->OnRailRoadTypeChange();
641 break;
642 }
643
645 RoadType temp = (RoadType)index;
646 if (temp == this->sel_roadtype) return; // we didn't select a new one. No need to change anything
647 this->sel_roadtype = temp;
648 this->OnRailRoadTypeChange();
649 break;
650 }
651
653 this->replace_engines = index != 0;
654 this->engines[0].ForceRebuild();
655 this->reset_sel_engine = true;
656 this->SetDirty();
657 break;
658 }
659
661 this->ReplaceClick_StartReplace(index != 0);
662 break;
663 }
664 }
665
666 bool OnTooltip([[maybe_unused]] Point pt, WidgetID widget, TooltipCloseCondition close_cond) override
667 {
668 if (widget != WID_RV_TRAIN_WAGONREMOVE_TOGGLE) return false;
669
670 if (Group::IsValidID(this->sel_group)) {
672 } else {
674 }
675 return true;
676 }
677
678 void OnResize() override
679 {
680 this->vscroll[0]->SetCapacityFromWidget(this, WID_RV_LEFT_MATRIX);
681 this->vscroll[1]->SetCapacityFromWidget(this, WID_RV_RIGHT_MATRIX);
682 }
683
689 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
690 {
691 if (data != 0) {
692 /* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */
693 this->engines[0].ForceRebuild();
694 } else {
695 this->engines[1].ForceRebuild();
696 }
697 }
698};
699
700static constexpr NWidgetPart _nested_replace_rail_vehicle_widgets[] = {
702 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
703 NWidget(WWT_CAPTION, COLOUR_GREY, WID_RV_CAPTION),
704 NWidget(WWT_SHADEBOX, COLOUR_GREY),
705 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
706 NWidget(WWT_STICKYBOX, COLOUR_GREY),
707 EndContainer(),
709 NWidget(WWT_PANEL, COLOUR_GREY),
710 NWidget(WWT_LABEL, INVALID_COLOUR), SetStringTip(STR_REPLACE_VEHICLE_VEHICLES_IN_USE, STR_REPLACE_VEHICLE_VEHICLES_IN_USE_TOOLTIP), SetFill(1, 1), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical()), SetResize(1, 0),
711 EndContainer(),
712 NWidget(WWT_PANEL, COLOUR_GREY),
713 NWidget(WWT_LABEL, INVALID_COLOUR), SetStringTip(STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES, STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES_TOOLTIP), SetFill(1, 1), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical()), SetResize(1, 0),
714 EndContainer(),
715 EndContainer(),
719 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_RAIL_TYPE_DROPDOWN), SetMinimalSize(136, 12), SetToolTip(STR_REPLACE_RAILTYPE_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
720 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN), SetToolTip(STR_REPLACE_ENGINE_WAGON_SELECT_TOOLTIP),
721 EndContainer(),
722 NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(),
723 EndContainer(),
726 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_SORT_ASCENDING_DESCENDING), SetStringTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), SetFill(1, 1),
727 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_SORT_DROPDOWN), SetResize(1, 0), SetFill(1, 1), SetToolTip(STR_TOOLTIP_SORT_CRITERIA),
728 EndContainer(),
730 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_SHOW_HIDDEN_ENGINES), SetStringTip(STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN, STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP),
731 NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(),
732 EndContainer(),
733 EndContainer(),
734 EndContainer(),
736 NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_LEFT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_LEFT_ARRAY_TOOLTIP), SetResize(1, 1), SetScrollbar(WID_RV_LEFT_SCROLLBAR),
738 NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_RIGHT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_RIGHT_ARRAY_TOOLTIP), SetResize(1, 1), SetScrollbar(WID_RV_RIGHT_SCROLLBAR),
740 EndContainer(),
742 NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_LEFT_DETAILS), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(),
745 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_TRAIN_WAGONREMOVE_TOGGLE), SetMinimalSize(138, 12), SetStringTip(STR_REPLACE_REMOVE_WAGON, STR_REPLACE_REMOVE_WAGON_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
746 EndContainer(),
747 EndContainer(),
749 NWidget(NWID_PUSHBUTTON_DROPDOWN, COLOUR_GREY, WID_RV_START_REPLACE), SetMinimalSize(139, 12), SetStringTip(STR_REPLACE_VEHICLES_START, STR_REPLACE_START_BUTTON_TOOLTIP),
750 NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_INFO_TAB), SetMinimalSize(167, 12), SetToolTip(STR_REPLACE_REPLACE_INFO_TAB_TOOLTIP), SetResize(1, 0),
751 EndContainer(),
752 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_STOP_REPLACE), SetMinimalSize(150, 12), SetStringTip(STR_REPLACE_VEHICLES_STOP, STR_REPLACE_STOP_BUTTON_TOOLTIP),
753 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
754 EndContainer(),
755};
756
757static WindowDesc _replace_rail_vehicle_desc(
758 WDP_AUTO, "replace_vehicle_train", 500, 140,
761 _nested_replace_rail_vehicle_widgets
762);
763
764static constexpr NWidgetPart _nested_replace_road_vehicle_widgets[] = {
766 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
767 NWidget(WWT_CAPTION, COLOUR_GREY, WID_RV_CAPTION),
768 NWidget(WWT_SHADEBOX, COLOUR_GREY),
769 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
770 NWidget(WWT_STICKYBOX, COLOUR_GREY),
771 EndContainer(),
773 NWidget(WWT_PANEL, COLOUR_GREY),
774 NWidget(WWT_LABEL, INVALID_COLOUR), SetStringTip(STR_REPLACE_VEHICLE_VEHICLES_IN_USE, STR_REPLACE_VEHICLE_VEHICLES_IN_USE_TOOLTIP), SetFill(1, 1), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical()), SetResize(1, 0),
775 EndContainer(),
776 NWidget(WWT_PANEL, COLOUR_GREY),
777 NWidget(WWT_LABEL, INVALID_COLOUR), SetStringTip(STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES, STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES_TOOLTIP), SetFill(1, 1), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical()), SetResize(1, 0),
778 EndContainer(),
779 EndContainer(),
782 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_ROAD_TYPE_DROPDOWN), SetMinimalSize(136, 12), SetToolTip(STR_REPLACE_ROADTYPE_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
783 NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(),
784 EndContainer(),
787 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_SORT_ASCENDING_DESCENDING), SetStringTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), SetFill(1, 1),
788 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_SORT_DROPDOWN), SetResize(1, 0), SetFill(1, 1), SetToolTip(STR_TOOLTIP_SORT_CRITERIA),
789 EndContainer(),
791 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_SHOW_HIDDEN_ENGINES), SetStringTip(STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN, STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP),
792 NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(),
793 EndContainer(),
794 EndContainer(),
795 EndContainer(),
797 NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_LEFT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_LEFT_ARRAY_TOOLTIP), SetResize(1, 1), SetScrollbar(WID_RV_LEFT_SCROLLBAR),
799 NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_RIGHT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_RIGHT_ARRAY_TOOLTIP), SetResize(1, 1), SetScrollbar(WID_RV_RIGHT_SCROLLBAR),
801 EndContainer(),
803 NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_LEFT_DETAILS), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(),
805 EndContainer(),
807 NWidget(NWID_PUSHBUTTON_DROPDOWN, COLOUR_GREY, WID_RV_START_REPLACE), SetMinimalSize(139, 12), SetStringTip(STR_REPLACE_VEHICLES_START, STR_REPLACE_START_BUTTON_TOOLTIP),
808 NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_INFO_TAB), SetMinimalSize(167, 12), SetToolTip(STR_REPLACE_REPLACE_INFO_TAB_TOOLTIP), SetResize(1, 0),
809 EndContainer(),
810 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_STOP_REPLACE), SetMinimalSize(150, 12), SetStringTip(STR_REPLACE_VEHICLES_STOP, STR_REPLACE_STOP_BUTTON_TOOLTIP),
811 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
812 EndContainer(),
813};
814
815static WindowDesc _replace_road_vehicle_desc(
816 WDP_AUTO, "replace_vehicle_road", 500, 140,
819 _nested_replace_road_vehicle_widgets
820);
821
822static constexpr NWidgetPart _nested_replace_vehicle_widgets[] = {
824 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
825 NWidget(WWT_CAPTION, COLOUR_GREY, WID_RV_CAPTION), SetMinimalSize(433, 14),
826 NWidget(WWT_SHADEBOX, COLOUR_GREY),
827 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
828 NWidget(WWT_STICKYBOX, COLOUR_GREY),
829 EndContainer(),
831 NWidget(WWT_PANEL, COLOUR_GREY),
832 NWidget(WWT_LABEL, INVALID_COLOUR), SetStringTip(STR_REPLACE_VEHICLE_VEHICLES_IN_USE, STR_REPLACE_VEHICLE_VEHICLES_IN_USE_TOOLTIP), SetFill(1, 1), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical()), SetResize(1, 0),
833 EndContainer(),
834 NWidget(WWT_PANEL, COLOUR_GREY),
835 NWidget(WWT_LABEL, INVALID_COLOUR), SetStringTip(STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES, STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES_TOOLTIP), SetFill(1, 1), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical()), SetResize(1, 0),
836 EndContainer(),
837 EndContainer(),
839 NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(),
842 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_SORT_ASCENDING_DESCENDING), SetStringTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
843 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_SORT_DROPDOWN), SetResize(1, 0), SetFill(1, 1), SetToolTip(STR_TOOLTIP_SORT_CRITERIA),
844 EndContainer(),
846 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_SHOW_HIDDEN_ENGINES), SetStringTip(STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN, STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP),
847 NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(),
848 EndContainer(),
849 EndContainer(),
850 EndContainer(),
852 NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_LEFT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_LEFT_ARRAY_TOOLTIP), SetResize(1, 1), SetScrollbar(WID_RV_LEFT_SCROLLBAR),
854 NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_RIGHT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_RIGHT_ARRAY_TOOLTIP), SetResize(1, 1), SetScrollbar(WID_RV_RIGHT_SCROLLBAR),
856 EndContainer(),
860 EndContainer(),
862 NWidget(NWID_PUSHBUTTON_DROPDOWN, COLOUR_GREY, WID_RV_START_REPLACE), SetMinimalSize(139, 12), SetStringTip(STR_REPLACE_VEHICLES_START, STR_REPLACE_START_BUTTON_TOOLTIP),
863 NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_INFO_TAB), SetMinimalSize(167, 12), SetToolTip(STR_REPLACE_REPLACE_INFO_TAB_TOOLTIP), SetResize(1, 0), EndContainer(),
864 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_STOP_REPLACE), SetMinimalSize(138, 12), SetStringTip(STR_REPLACE_VEHICLES_STOP, STR_REPLACE_STOP_BUTTON_TOOLTIP),
865 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
866 EndContainer(),
867};
868
869static WindowDesc _replace_vehicle_desc(
870 WDP_AUTO, "replace_vehicle", 456, 118,
873 _nested_replace_vehicle_widgets
874);
875
882{
884 switch (vehicletype) {
885 case VEH_TRAIN: new ReplaceVehicleWindow(_replace_rail_vehicle_desc, vehicletype, id_g); break;
886 case VEH_ROAD: new ReplaceVehicleWindow(_replace_road_vehicle_desc, vehicletype, id_g); break;
887 default: new ReplaceVehicleWindow(_replace_vehicle_desc, vehicletype, id_g); break;
888 }
889}
bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company)
Checks some basic properties whether autoreplace is allowed.
Command definitions related to autoreplace.
Functions related to autoreplacing.
bool EngineHasReplacementWhenOldForCompany(const Company *c, EngineID engine, GroupID group)
Check if a company has a replacement set up for the given engine when it gets old.
EngineID EngineReplacementForCompany(const Company *c, EngineID engine, GroupID group, bool *replace_when_old=nullptr)
Retrieve the engine replacement for the given company and original engine type.
bool EngineHasReplacementForCompany(const Company *c, EngineID engine, GroupID group)
Check if a company has a replacement set up for the given engine.
void ShowReplaceGroupVehicleWindow(GroupID id_g, VehicleType vehicletype)
Show the autoreplace configuration window for a particular group.
void InvalidateAutoreplaceWindow(EngineID e, GroupID id_g)
Rebuild the left autoreplace list if an engine is removed or added.
void AddRemoveEngineFromAutoreplaceAndBuildWindows(VehicleType type)
When an engine is made buildable or is removed from being buildable, add/remove it from the build/aut...
Types related to the autoreplace widgets.
@ WID_RV_SHOW_HIDDEN_ENGINES
Toggle whether to display the hidden vehicles.
@ WID_RV_TRAIN_ENGINEWAGON_DROPDOWN
Dropdown to select engines and/or wagons.
@ WID_RV_LEFT_SCROLLBAR
The scrollbar for the matrix on the left.
@ WID_RV_CAPTION
Caption of the window.
@ WID_RV_RIGHT_DETAILS
Details of the entry on the right.
@ WID_RV_TRAIN_WAGONREMOVE_TOGGLE
Button to toggle removing wagons.
@ WID_RV_STOP_REPLACE
Stop Replacing button.
@ WID_RV_ROAD_TYPE_DROPDOWN
Dropdown to select roadtype.
@ WID_RV_RIGHT_MATRIX
The matrix on the right.
@ WID_RV_INFO_TAB
Info tab.
@ WID_RV_RAIL_TYPE_DROPDOWN
Dropdown to select railtype.
@ WID_RV_LEFT_MATRIX
The matrix on the left.
@ WID_RV_SORT_ASCENDING_DESCENDING
Ascending/descending sort order button.
@ WID_RV_RIGHT_SCROLLBAR
The scrollbar for the matrix on the right.
@ WID_RV_START_REPLACE
Start Replacing button.
@ WID_RV_SORT_DROPDOWN
Dropdown for the sort criteria.
@ WID_RV_LEFT_DETAILS
Details of the entry on the left.
void GUIEngineListAddChildren(GUIEngineList &dst, const GUIEngineList &src, EngineID parent, uint8_t indent)
Add children to GUI engine list to build a hierarchical tree.
void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_list, const Scrollbar &sb, EngineID selected_id, bool show_count, GroupID selected_group, const GUIBadgeClasses &badge_classes)
Engine drawing loop.
bool _engine_sort_last_order[]
Last set direction of the sort order, for each vehicle type.
uint GetEngineListHeight(VehicleType type)
Get the height of a single 'entry' in the engine lists.
const std::initializer_list< const StringID > _engine_sort_listing[]
Dropdown menu strings for the vehicle sort criteria.
uint8_t _engine_sort_last_criteria[]
Last set sort criteria, for each vehicle type.
int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number, TestedEngineDetails &te)
Draw the purchase info details of a vehicle at a given location.
EngList_SortTypeFunction *const _engine_sort_functions[][11]
Sort functions for the vehicle sort criteria, for each vehicle type.
void DisplayVehicleSortDropDown(Window *w, VehicleType vehicle_type, int selected, WidgetID button)
Display the dropdown for the vehicle sort criteria.
bool _engine_sort_direction
false = descending, true = ascending.
bool _engine_sort_show_hidden_engines[]
Last set 'show hidden engines' setting for each vehicle type.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Timpl & Flip(Tvalue_type value)
Flip the value-th bit.
Base class for a 'real' widget.
void SetLowered(bool lowered)
Lower or raise the widget.
void SetStringTip(StringID string, StringID tool_tip)
Set string and tool tip of the nested widget.
Definition widget.cpp:1138
struct RailTypeInfo::@24 strings
Strings associated with the rail type.
StringID replace_text
Text used in the autoreplace GUI.
Definition rail.h:171
Window for the autoreplacing of vehicles.
void OnInit() override
Notification that the nested widget tree gets initialized.
void OnResize() override
Called after the window got resized.
bool GenerateReplaceRailList(EngineID e, bool draw_left, bool show_engines)
Figure out if an engine should be added to a list.
void OnDropdownSelect(WidgetID widget, int index) override
A dropdown option associated to this window has been selected.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
void ReplaceClick_StartReplace(bool replace_when_old)
Handle click on the start replace button.
bool OnTooltip(Point pt, WidgetID widget, TooltipCloseCondition close_cond) override
Event to display a custom tooltip.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
uint8_t sort_criteria
Criteria of sorting vehicles.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
RailType sel_railtype
Type of rail tracks selected. INVALID_RAILTYPE to show all.
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.
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
bool replace_engines
If true, engines are replaced, if false, wagons are replaced (only for trains).
bool reset_sel_engine
Also reset sel_engine while updating left and/or right and no valid engine selected.
void OnPaint() override
The window must be repainted.
bool show_hidden_engines
Whether to show the hidden engines.
void GenerateLists()
Generate the lists.
RoadType sel_roadtype
Type of road selected. INVALID_ROADTYPE to show all.
std::array< GUIEngineList, 2 > engines
Left and right list of engines.
VehicleType vehicle_type
Type of vehicle in this window.
int details_height
Minimal needed height of the details panels, in text lines (found so far).
void GenerateReplaceVehList(bool draw_left)
Generate an engines list.
GroupID sel_group
Group selected to replace.
std::array< EngineID, 2 > sel_engine
Selected engine left and right.
bool descending_sort_order
Order of sorting vehicles.
void OnRailRoadTypeChange()
Perform tasks after rail or road type is changed.
StringID replace_text
Text used in the autoreplace GUI.
Definition road.h:98
struct RoadTypeInfo::@27 strings
Strings associated with the rail type.
RectPadding framerect
Standard padding inside many panels.
Definition window_gui.h:40
RectPadding frametext
Padding inside frame with text.
Definition window_gui.h:41
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:29
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition window_gui.h:94
Functions related to commands.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Functions related to companies.
void ShowDropDownMenu(Window *w, std::span< const StringID > strings, int selected, WidgetID button, uint32_t disabled_mask, uint32_t hidden_mask, uint width)
Show a dropdown menu window near a widget of the parent window.
Definition dropdown.cpp:441
void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width, bool instant_close, bool persist)
Show a drop down list.
Definition dropdown.cpp:404
Functions related to the drop down widget.
Types related to the drop down widget.
std::vector< std::unique_ptr< const DropDownListItem > > DropDownList
A drop down list is a collection of drop down list items.
Base class for engines.
@ HasVariants
Set if engine has variants.
@ IsFolded
Set if display of variants should be folded (hidden).
@ Shaded
Set if engine should be masked.
void EngList_Sort(GUIEngineList &el, EngList_SortTypeFunction compare)
Sort all items using quick sort and given 'CompareItems' function.
Engine GUI functions, used by build_vehicle_gui and autoreplace_gui
uint64_t PackEngineNameDParam(EngineID engine_id, EngineNameContext context, uint32_t extra_data=0)
Combine an engine ID and a name context to an engine name dparam.
@ PurchaseList
Name is shown in the purchase list (including autoreplace window 'Available vehicles' panel).
@ RAILVEH_WAGON
simple wagon, not motorized
Definition engine_type.h:33
fluid_settings_t * settings
FluidSynth settings handle.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:77
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Geometry functions.
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:852
Dimension GetStringListBoundingBox(std::span< const StringID > list, FontSize fontsize)
Get maximum dimension of a list of strings.
Definition gfx.cpp:890
int DrawString(int left, int right, int top, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition gfx.cpp:658
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:38
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:243
@ SA_HOR_CENTER
Horizontally center the text.
Definition gfx_type.h:376
@ ReplaceWagonRemoval
If set, autoreplace will perform wagon removal on vehicles in this group.
uint GetGroupNumEngines(CompanyID company, GroupID id_g, EngineID id_e)
Get the number of engines with EngineID id_e in the group with GroupID id_g and its sub-groups.
constexpr NWidgetPart SetMatrixDataTip(uint32_t cols, uint32_t rows, StringID tip={})
Widget part function for setting the data and tooltip of WWT_MATRIX widgets.
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
constexpr NWidgetPart SetScrollbar(WidgetID index)
Attach a scrollbar to a widget.
constexpr NWidgetPart SetStringTip(StringID string, StringID tip={})
Widget part function for setting the string and tooltip.
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=-1)
Widget part function for starting a new 'real' widget.
constexpr NWidgetPart SetToolTip(StringID tip)
Widget part function for setting tooltip and clearing the widget data.
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
constexpr NWidgetPart SetMinimalTextLines(uint8_t lines, uint8_t spacing, FontSize size=FS_NORMAL)
Widget part function for setting the minimal text lines.
constexpr NWidgetPart SetResize(int16_t dx, int16_t dy)
Widget part function for setting the resize step.
Command definitions related to engine groups.
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition window.cpp:943
static constexpr GroupID DEFAULT_GROUP
Ungrouped vehicles are in this group.
Definition group_type.h:18
static constexpr GroupID ALL_GROUP
All vehicles are in this group.
Definition group_type.h:17
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
void GuiShowTooltips(Window *parent, EncodedString &&text, TooltipCloseCondition close_tooltip)
Shows a tooltip.
Definition misc_gui.cpp:690
GrfSpecFeature
Definition newgrf.h:68
Functions related to NewGRF badges.
Functions for NewGRF engines.
Rail specific functions.
const RailTypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition rail.h:300
DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option)
Create a drop down list for all the rail types of the local company.
Functions/types etc.
RailType
Enumeration for all possible railtypes.
Definition rail_type.h:27
@ INVALID_RAILTYPE
Flag for invalid railtype.
Definition rail_type.h:34
Road specific functions.
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:220
Functions/types related to the road GUIs.
RoadType
The different roadtypes we support.
Definition road_type.h:25
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:30
A number of safeguards to prevent using unsafe methods.
Command definitions related to settings.
Functions related to setting/changing the settings.
Definition of base types and functions in a cross-platform compatible way.
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:426
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:56
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
@ TD_RTL
Text is written right-to-left by default.
CompanySettings settings
settings specific for each company
bool renew_keep_length
sell some wagons if after autoreplace the train is longer than before
Dimensions (a width and height) of a rectangle in 2D.
static Pool::IterateWrapperFiltered< Engine, EngineTypeFilter > IterateType(VehicleType vt, size_t from=0)
Returns an iterable ensemble of all valid engines of the given type.
EngineDisplayFlags display_flags
NOSAVE client-side-only display flags for build engine list.
Definition engine_base.h:63
EngineID engine_id
Engine to display in build purchase list.
Definition engine_gui.h:22
Group data.
Definition group.h:72
GroupFlags flags
Group flags.
Definition group.h:77
Partial widget specification to allow NWidgets to be written nested.
Coordinates of a point in 2D.
static Titem * Get(auto index)
Returns Titem with given index.
static bool IsValidID(auto index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
static Titem * GetIfValid(auto index)
Returns Titem with given index.
Information about a rail vehicle.
Definition engine_type.h:46
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.
Extra information about refitted cargo and capacity.
Definition vehicle_gui.h:42
Money cost
Refit cost.
Definition vehicle_gui.h:43
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:955
static int SortButtonWidth()
Get width of up/down arrow of sort button state.
Definition widget.cpp:793
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1736
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:744
Window * parent
Parent window.
Definition window_gui.h:329
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
Definition window.cpp:502
void DrawSortButtonState(WidgetID widget, SortButtonState state) const
Draw a sort button's up or down arrow symbol.
Definition widget.cpp:776
ResizeInfo resize
Resize information.
Definition window_gui.h:315
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1726
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
bool IsShaded() const
Is window shaded currently?
Definition window_gui.h:558
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:973
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:593
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition window.cpp:311
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:382
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:303
Functions related to the vehicle's GUIs.
VehicleType
Available vehicle types.
@ VEH_INVALID
Non-existing type of vehicle.
@ VEH_ROAD
Road vehicle type.
@ VEH_TRAIN
Train vehicle type.
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
@ WWT_LABEL
Centered label.
Definition widget_type.h:47
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:65
@ WWT_TEXTBTN
(Toggle) Button with text
Definition widget_type.h:45
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:40
@ WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition widget_type.h:56
@ WWT_MATRIX
Grid of rows and columns.
Definition widget_type.h:49
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition widget_type.h:54
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition widget_type.h:51
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition widget_type.h:75
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:67
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:59
@ WWT_RESIZEBOX
Resize box (normally at bottom-right of a window)
Definition widget_type.h:58
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition widget_type.h:55
@ WWT_DROPDOWN
Drop down list.
Definition widget_type.h:60
@ 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:1143
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition window.cpp:3224
void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope)
Mark window data of all windows of a given class as invalid (in need of re-computing) Note that by de...
Definition window.cpp:3241
Window functions not directly related to making/drawing windows.
Functions, definitions and such used only by the GUI.
@ Construction
This window is used for construction; close it whenever changing company.
@ SBS_DOWN
Sort ascending.
Definition window_gui.h:219
@ SBS_UP
Sort descending.
Definition window_gui.h:220
@ WDP_AUTO
Find a place automatically.
Definition window_gui.h:145
int WidgetID
Widget ID.
Definition window_type.h:20
@ WC_REPLACE_VEHICLE
Replace vehicle window; Window numbers:
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:47
@ WC_BUILD_VEHICLE
Build vehicle; Window numbers: