OpenTTD Source 20250311-master-g40ddc03423
road_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 "gui.h"
12#include "window_gui.h"
13#include "station_gui.h"
14#include "terraform_gui.h"
15#include "viewport_func.h"
16#include "command_func.h"
17#include "road_cmd.h"
18#include "station_func.h"
19#include "waypoint_func.h"
20#include "window_func.h"
21#include "vehicle_func.h"
22#include "sound_func.h"
23#include "company_func.h"
24#include "tunnelbridge.h"
25#include "tunnelbridge_map.h"
26#include "tilehighlight_func.h"
27#include "company_base.h"
28#include "hotkeys.h"
29#include "road_gui.h"
30#include "zoom_func.h"
31#include "dropdown_type.h"
32#include "dropdown_func.h"
33#include "engine_base.h"
34#include "station_base.h"
35#include "waypoint_base.h"
36#include "strings_func.h"
38#include "station_cmd.h"
39#include "waypoint_cmd.h"
40#include "road_cmd.h"
41#include "tunnelbridge_cmd.h"
42#include "newgrf_badge.h"
43#include "newgrf_roadstop.h"
44#include "picker_gui.h"
45#include "timer/timer.h"
47
48#include "widgets/road_widget.h"
49
50#include "table/strings.h"
51
52#include "safeguards.h"
53
54static void ShowRVStationPicker(Window *parent, RoadStopType rs);
55static void ShowRoadDepotPicker(Window *parent);
56static void ShowBuildRoadWaypointPicker(Window *parent);
57
58static bool _remove_button_clicked;
59static bool _one_way_button_clicked;
60
61static Axis _place_road_dir;
62static bool _place_road_start_half_x;
63static bool _place_road_start_half_y;
64static bool _place_road_end_half;
65
66static RoadType _cur_roadtype;
67
68static DiagDirection _road_depot_orientation;
69
75
81static RoadStopPickerSelection _roadstop_gui;
82
83static bool IsRoadStopEverAvailable(const RoadStopSpec *spec, StationType type)
84{
85 if (spec == nullptr) return true;
86
87 if (spec->flags.Test(RoadStopSpecFlag::RoadOnly) && !RoadTypeIsRoad(_cur_roadtype)) return false;
88 if (spec->flags.Test(RoadStopSpecFlag::TramOnly) && !RoadTypeIsTram(_cur_roadtype)) return false;
89
90 switch (spec->stop_type) {
91 case ROADSTOPTYPE_ALL: return true;
92 case ROADSTOPTYPE_PASSENGER: return type == StationType::Bus;
93 case ROADSTOPTYPE_FREIGHT: return type == StationType::Truck;
94 default: NOT_REACHED();
95 }
96}
97
102static bool IsRoadStopAvailable(const RoadStopSpec *spec, StationType type)
103{
104 if (spec == nullptr) return true;
105 if (!IsRoadStopEverAvailable(spec, type)) return false;
106
107 if (!spec->callback_mask.Test(RoadStopCallbackMask::Avail)) return true;
108
109 uint16_t cb_res = GetRoadStopCallback(CBID_STATION_AVAILABILITY, 0, 0, spec, nullptr, INVALID_TILE, _cur_roadtype, type, 0);
110 if (cb_res == CALLBACK_FAILED) return true;
111
113}
114
115void CcPlaySound_CONSTRUCTION_OTHER(Commands, const CommandCost &result, TileIndex tile)
116{
117 if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile);
118}
119
124static void PlaceRoad_Bridge(TileIndex tile, Window *w)
125{
126 if (IsBridgeTile(tile)) {
127 TileIndex other_tile = GetOtherTunnelBridgeEnd(tile);
128 Point pt = {0, 0};
129 w->OnPlaceMouseUp(VPM_X_OR_Y, DDSP_BUILD_BRIDGE, pt, other_tile, tile);
130 } else {
132 }
133}
134
141void CcBuildRoadTunnel(Commands, const CommandCost &result, TileIndex start_tile)
142{
143 if (result.Succeeded()) {
144 if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, start_tile);
146
147 DiagDirection start_direction = ReverseDiagDir(GetTunnelBridgeDirection(start_tile));
148 ConnectRoadToStructure(start_tile, start_direction);
149
150 TileIndex end_tile = GetOtherTunnelBridgeEnd(start_tile);
151 DiagDirection end_direction = ReverseDiagDir(GetTunnelBridgeDirection(end_tile));
152 ConnectRoadToStructure(end_tile, end_direction);
153 } else {
155 }
156}
157
164{
165 tile += TileOffsByDiagDir(direction);
166 /* if there is a roadpiece just outside of the station entrance, build a connecting route */
167 if (IsNormalRoadTile(tile)) {
168 if (GetRoadBits(tile, GetRoadTramType(_cur_roadtype)) != ROAD_NONE) {
169 Command<CMD_BUILD_ROAD>::Post(tile, DiagDirToRoadBits(ReverseDiagDir(direction)), _cur_roadtype, DRD_NONE, TownID::Invalid());
170 }
171 }
172}
173
174void CcRoadDepot(Commands, const CommandCost &result, TileIndex tile, RoadType, DiagDirection dir)
175{
176 if (result.Failed()) return;
177
180 ConnectRoadToStructure(tile, dir);
181}
182
195void CcRoadStop(Commands, const CommandCost &result, TileIndex tile, uint8_t width, uint8_t length, RoadStopType, bool is_drive_through,
196 DiagDirection dir, RoadType, RoadStopClassID spec_class, uint16_t spec_index, StationID, bool)
197{
198 if (result.Failed()) return;
199
202
203 bool connect_to_road = true;
204 if ((uint)spec_class < RoadStopClass::GetClassCount() && spec_index < RoadStopClass::Get(spec_class)->GetSpecCount()) {
205 const RoadStopSpec *roadstopspec = RoadStopClass::Get(spec_class)->GetSpec(spec_index);
206 if (roadstopspec != nullptr && roadstopspec->flags.Test(RoadStopSpecFlag::NoAutoRoadConnection)) connect_to_road = false;
207 }
208
209 if (connect_to_road) {
210 TileArea roadstop_area(tile, width, length);
211 for (TileIndex cur_tile : roadstop_area) {
212 ConnectRoadToStructure(cur_tile, dir);
213 /* For a drive-through road stop build connecting road for other entrance. */
214 if (is_drive_through) ConnectRoadToStructure(cur_tile, ReverseDiagDir(dir));
215 }
216 }
217}
218
229static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, RoadStopType stop_type, bool adjacent, RoadType rt, StringID err_msg)
230{
231 TileArea ta(start_tile, end_tile);
232 DiagDirection ddir = _roadstop_gui.orientation;
233 bool drive_through = ddir >= DIAGDIR_END;
234 if (drive_through) ddir = static_cast<DiagDirection>(ddir - DIAGDIR_END); // Adjust picker result to actual direction.
235 RoadStopClassID spec_class = _roadstop_gui.sel_class;
236 uint16_t spec_index = _roadstop_gui.sel_type;
237
238 auto proc = [=](bool test, StationID to_join) -> bool {
239 if (test) {
240 return Command<CMD_BUILD_ROAD_STOP>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_ROAD_STOP>()), ta.tile, ta.w, ta.h, stop_type, drive_through,
241 ddir, rt, spec_class, spec_index, StationID::Invalid(), adjacent).Succeeded();
242 } else {
243 return Command<CMD_BUILD_ROAD_STOP>::Post(err_msg, CcRoadStop, ta.tile, ta.w, ta.h, stop_type, drive_through,
244 ddir, rt, spec_class, spec_index, to_join, adjacent);
245 }
246 };
247
249}
250
256{
257 if (_remove_button_clicked) {
259 return;
260 }
261
262 Axis axis = GetAxisForNewRoadWaypoint(tile);
263 if (IsValidAxis(axis)) {
264 /* Valid tile for waypoints */
266 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
267 } else {
268 /* Tile where we can't build road waypoints. This is always going to fail,
269 * but provides the user with a proper error message. */
270 Command<CMD_BUILD_ROAD_WAYPOINT>::Post(STR_ERROR_CAN_T_BUILD_ROAD_WAYPOINT, tile, AXIS_X, 1, 1, ROADSTOP_CLASS_WAYP, 0, StationID::Invalid(), false);
271 }
272}
273
279{
280 if (_remove_button_clicked) {
282 } else {
283 if (_roadstop_gui.orientation < DIAGDIR_END) { // Not a drive-through stop.
285 } else {
287 }
288 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
289 }
290}
291
297{
298 if (_remove_button_clicked) {
300 } else {
301 if (_roadstop_gui.orientation < DIAGDIR_END) { // Not a drive-through stop.
303 } else {
305 }
306 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
307 }
308}
309
310typedef void OnButtonClick(Window *w);
311
317{
320 _remove_button_clicked = w->IsWidgetLowered(WID_ROT_REMOVE);
321 SetSelectionRed(_remove_button_clicked);
322}
323
330{
331 if (w->IsWidgetDisabled(WID_ROT_REMOVE)) return false;
332
333 /* allow ctrl to switch remove mode only for these widgets */
334 for (WidgetID i = WID_ROT_ROAD_X; i <= WID_ROT_AUTOROAD; i++) {
335 if (w->IsWidgetLowered(i)) {
337 return true;
338 }
339 }
340
341 return false;
342}
343
347 int last_started_action = INVALID_WID_ROT;
348
350 {
351 this->CreateNestedTree();
352 this->FinishInitNested(window_number);
354
355 if (RoadTypeIsRoad(this->roadtype)) {
357 }
358
359 this->OnInvalidateData();
360
362 }
363
364 void Close([[maybe_unused]] int data = 0) override
365 {
366 if (_game_mode == GM_NORMAL && (this->IsWidgetLowered(WID_ROT_BUS_STATION) || this->IsWidgetLowered(WID_ROT_TRUCK_STATION))) SetViewportCatchmentStation(nullptr, true);
368 this->Window::Close();
369 }
370
376 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
377 {
378 if (!gui_scope) return;
379
380 if (!ValParamRoadType(this->roadtype)) {
381 /* Close toolbar if road type is not available. */
382 this->Close();
383 return;
384 }
385
386 RoadTramType rtt = GetRoadTramType(this->roadtype);
387
389 this->SetWidgetsDisabledState(!can_build,
394 if (!can_build) {
399 }
400
401 if (_game_mode != GM_EDITOR) {
402 if (!can_build) {
403 /* Show in the tooltip why this button is disabled. */
408 } else {
413 }
414 }
415 }
416
417 void OnInit() override
418 {
419 /* Configure the road toolbar for the roadtype. */
420 const RoadTypeInfo *rti = GetRoadTypeInfo(this->roadtype);
424 if (_game_mode != GM_EDITOR) {
426 }
429 }
430
436 {
437 this->roadtype = roadtype;
438 this->ReInit();
439 }
440
441 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
442 {
443 if (widget == WID_ROT_CAPTION) {
444 const RoadTypeInfo *rti = GetRoadTypeInfo(this->roadtype);
445 if (rti->max_speed > 0) {
447 }
448 return GetString(rti->strings.toolbar_caption);
449
450 }
451
452 return this->Window::GetWidgetString(widget, stringid);
453 }
454
461 {
462 /* The remove and the one way button state is driven
463 * by the other buttons so they don't act on themselves.
464 * Both are only valid if they are able to apply as options. */
465 switch (clicked_widget) {
466 case WID_ROT_REMOVE:
467 if (RoadTypeIsRoad(this->roadtype)) {
470 }
471
472 break;
473
474 case WID_ROT_ONE_WAY:
477 break;
478
482 if (RoadTypeIsRoad(this->roadtype)) this->DisableWidget(WID_ROT_ONE_WAY);
483 this->SetWidgetDisabledState(WID_ROT_REMOVE, !this->IsWidgetLowered(clicked_widget));
484 break;
485
486 case WID_ROT_ROAD_X:
487 case WID_ROT_ROAD_Y:
488 case WID_ROT_AUTOROAD:
489 this->SetWidgetDisabledState(WID_ROT_REMOVE, !this->IsWidgetLowered(clicked_widget));
490 if (RoadTypeIsRoad(this->roadtype)) {
491 this->SetWidgetDisabledState(WID_ROT_ONE_WAY, !this->IsWidgetLowered(clicked_widget));
492 }
493 break;
494
495 default:
496 /* When any other buttons than road/station, raise and
497 * disable the removal button */
500
501 if (RoadTypeIsRoad(this->roadtype)) {
504 }
505
506 break;
507 }
508 }
509
510 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
511 {
512 _remove_button_clicked = false;
513 _one_way_button_clicked = false;
514 switch (widget) {
515 case WID_ROT_ROAD_X:
517 this->last_started_action = widget;
518 break;
519
520 case WID_ROT_ROAD_Y:
522 this->last_started_action = widget;
523 break;
524
525 case WID_ROT_AUTOROAD:
527 this->last_started_action = widget;
528 break;
529
530 case WID_ROT_DEMOLISH:
532 this->last_started_action = widget;
533 break;
534
535 case WID_ROT_DEPOT:
536 if (HandlePlacePushButton(this, WID_ROT_DEPOT, GetRoadTypeInfo(this->roadtype)->cursor.depot, HT_RECT)) {
537 ShowRoadDepotPicker(this);
538 this->last_started_action = widget;
539 }
540 break;
541
543 this->last_started_action = widget;
544 if (HandlePlacePushButton(this, WID_ROT_BUILD_WAYPOINT, SPR_CURSOR_WAYPOINT, HT_RECT)) {
545 ShowBuildRoadWaypointPicker(this);
546 }
547 break;
548
550 if (HandlePlacePushButton(this, WID_ROT_BUS_STATION, SPR_CURSOR_BUS_STATION, HT_RECT)) {
551 ShowRVStationPicker(this, RoadStopType::Bus);
552 this->last_started_action = widget;
553 }
554 break;
555
557 if (HandlePlacePushButton(this, WID_ROT_TRUCK_STATION, SPR_CURSOR_TRUCK_STATION, HT_RECT)) {
558 ShowRVStationPicker(this, RoadStopType::Truck);
559 this->last_started_action = widget;
560 }
561 break;
562
563 case WID_ROT_ONE_WAY:
564 if (this->IsWidgetDisabled(WID_ROT_ONE_WAY)) return;
565 this->SetDirty();
567 SetSelectionRed(false);
568 break;
569
571 HandlePlacePushButton(this, WID_ROT_BUILD_BRIDGE, SPR_CURSOR_BRIDGE, HT_RECT);
572 this->last_started_action = widget;
573 break;
574
577 this->last_started_action = widget;
578 break;
579
580 case WID_ROT_REMOVE:
581 if (this->IsWidgetDisabled(WID_ROT_REMOVE)) return;
582
586 break;
587
590 this->last_started_action = widget;
591 break;
592
593 default: NOT_REACHED();
594 }
597 }
598
600 {
601 MarkTileDirtyByTile(TileVirtXY(_thd.pos.x, _thd.pos.y)); // redraw tile selection
602 return Window::OnHotkey(hotkey);
603 }
604
605 void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override
606 {
607 _remove_button_clicked = this->IsWidgetLowered(WID_ROT_REMOVE);
608 _one_way_button_clicked = RoadTypeIsRoad(this->roadtype) ? this->IsWidgetLowered(WID_ROT_ONE_WAY) : false;
609 switch (this->last_started_action) {
610 case WID_ROT_ROAD_X:
611 _place_road_dir = AXIS_X;
612 _place_road_start_half_x = _tile_fract_coords.x >= 8;
614 break;
615
616 case WID_ROT_ROAD_Y:
617 _place_road_dir = AXIS_Y;
618 _place_road_start_half_y = _tile_fract_coords.y >= 8;
620 break;
621
622 case WID_ROT_AUTOROAD:
623 _place_road_dir = INVALID_AXIS;
624 _place_road_start_half_x = _tile_fract_coords.x >= 8;
625 _place_road_start_half_y = _tile_fract_coords.y >= 8;
627 break;
628
629 case WID_ROT_DEMOLISH:
631 break;
632
633 case WID_ROT_DEPOT:
634 Command<CMD_BUILD_ROAD_DEPOT>::Post(GetRoadTypeInfo(this->roadtype)->strings.err_depot, CcRoadDepot,
635 tile, _cur_roadtype, _road_depot_orientation);
636 break;
637
639 PlaceRoad_Waypoint(tile);
640 break;
641
644 break;
645
648 break;
649
651 PlaceRoad_Bridge(tile, this);
652 break;
653
656 tile, TRANSPORT_ROAD, _cur_roadtype);
657 break;
658
661 break;
662
663 default: NOT_REACHED();
664 }
665 }
666
687
689 {
690 /* Here we update the end tile flags
691 * of the road placement actions.
692 * At first we reset the end halfroad
693 * bits and if needed we set them again. */
694 switch (select_proc) {
696 _place_road_end_half = pt.x & 8;
697 break;
698
700 _place_road_end_half = pt.y & 8;
701 break;
702
704 /* For autoroad we need to update the
705 * direction of the road */
706 if (_thd.size.x > _thd.size.y || (_thd.size.x == _thd.size.y &&
707 ( (_tile_fract_coords.x < _tile_fract_coords.y && (_tile_fract_coords.x + _tile_fract_coords.y) < 16) ||
708 (_tile_fract_coords.x > _tile_fract_coords.y && (_tile_fract_coords.x + _tile_fract_coords.y) > 16) ))) {
709 /* Set dir = X */
710 _place_road_dir = AXIS_X;
711 _place_road_end_half = pt.x & 8;
712 } else {
713 /* Set dir = Y */
714 _place_road_dir = AXIS_Y;
715 _place_road_end_half = pt.y & 8;
716 }
717
718 break;
719
720 default:
721 break;
722 }
723
724 VpSelectTilesWithMethod(pt.x, pt.y, select_method);
725 }
726
727 void OnPlaceMouseUp([[maybe_unused]] ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt, TileIndex start_tile, TileIndex end_tile) override
728 {
729 if (pt.x != -1) {
730 switch (select_proc) {
731 default: NOT_REACHED();
734 ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, _cur_roadtype);
735 break;
736
738 GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
739 break;
740
743 case DDSP_PLACE_AUTOROAD: {
744 bool start_half = _place_road_dir == AXIS_Y ? _place_road_start_half_y : _place_road_start_half_x;
745
746 if (_remove_button_clicked) {
747 Command<CMD_REMOVE_LONG_ROAD>::Post(GetRoadTypeInfo(this->roadtype)->strings.err_remove_road, CcPlaySound_CONSTRUCTION_OTHER,
748 end_tile, start_tile, _cur_roadtype, _place_road_dir, start_half, _place_road_end_half);
749 } else {
750 Command<CMD_BUILD_LONG_ROAD>::Post(GetRoadTypeInfo(this->roadtype)->strings.err_build_road, CcPlaySound_CONSTRUCTION_OTHER,
751 end_tile, start_tile, _cur_roadtype, _place_road_dir, _one_way_button_clicked ? DRD_NORTHBOUND : DRD_NONE, start_half, _place_road_end_half, false);
752 }
753 break;
754 }
755
759 if (_remove_button_clicked) {
760 Command<CMD_REMOVE_FROM_ROAD_WAYPOINT>::Post(STR_ERROR_CAN_T_REMOVE_ROAD_WAYPOINT, CcPlaySound_CONSTRUCTION_OTHER, end_tile, start_tile);
761 } else {
762 TileArea ta(start_tile, end_tile);
763 Axis axis = select_method == VPM_X_LIMITED ? AXIS_X : AXIS_Y;
764 bool adjacent = _ctrl_pressed;
765
766 auto proc = [=](bool test, StationID to_join) -> bool {
767 if (test) {
769 } else {
771 }
772 };
773
775 }
776 }
777 break;
778
781 if (this->IsWidgetLowered(WID_ROT_BUS_STATION) && GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui.sel_class), RoadStopType::Bus, _cur_roadtype)) {
782 if (_remove_button_clicked) {
783 TileArea ta(start_tile, end_tile);
785 Command<CMD_REMOVE_ROAD_STOP>::Post(str, CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w, ta.h, RoadStopType::Bus, _ctrl_pressed);
786 } else {
788 PlaceRoadStop(start_tile, end_tile, RoadStopType::Bus, _ctrl_pressed, _cur_roadtype, str);
789 }
790 }
791 break;
792
795 if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION) && GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui.sel_class), RoadStopType::Truck, _cur_roadtype)) {
796 if (_remove_button_clicked) {
797 TileArea ta(start_tile, end_tile);
799 Command<CMD_REMOVE_ROAD_STOP>::Post(str, CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w, ta.h, RoadStopType::Truck, _ctrl_pressed);
800 } else {
802 PlaceRoadStop(start_tile, end_tile, RoadStopType::Truck, _ctrl_pressed, _cur_roadtype, str);
803 }
804 }
805 break;
806
808 Command<CMD_CONVERT_ROAD>::Post(GetRoadTypeInfo(this->roadtype)->strings.err_convert_road, CcPlaySound_CONSTRUCTION_OTHER, end_tile, start_tile, _cur_roadtype);
809 break;
810 }
811 }
812 }
813
819
821 {
822 if (RoadToolbar_CtrlChanged(this)) return ES_HANDLED;
823 return ES_NOT_HANDLED;
824 }
825
826 void OnRealtimeTick([[maybe_unused]] uint delta_ms) override
827 {
828 if (_game_mode == GM_NORMAL && this->IsWidgetLowered(WID_ROT_BUILD_WAYPOINT)) CheckRedrawRoadWaypointCoverage(this);
829 }
830
838 {
839 Window *w = nullptr;
840 switch (_game_mode) {
841 case GM_NORMAL:
843 break;
844
845 case GM_EDITOR:
846 if ((GetRoadTypes(true) & ((rtt == RTT_ROAD) ? ~_roadtypes_type : _roadtypes_type)) == ROADTYPES_NONE) return ES_NOT_HANDLED;
848 break;
849
850 default:
851 break;
852 }
853
854 if (w == nullptr) return ES_NOT_HANDLED;
855 return w->OnHotkey(hotkey);
856 }
857
858 static EventState RoadToolbarGlobalHotkeys(int hotkey)
859 {
860 extern RoadType _last_built_roadtype;
861 return RoadTramToolbarGlobalHotkeys(hotkey, _last_built_roadtype, RTT_ROAD);
862 }
863
864 static EventState TramToolbarGlobalHotkeys(int hotkey)
865 {
866 extern RoadType _last_built_tramtype;
867 return RoadTramToolbarGlobalHotkeys(hotkey, _last_built_tramtype, RTT_TRAM);
868 }
869
870 static inline HotkeyList road_hotkeys{"roadtoolbar", {
871 Hotkey('1', "build_x", WID_ROT_ROAD_X),
872 Hotkey('2', "build_y", WID_ROT_ROAD_Y),
873 Hotkey('3', "autoroad", WID_ROT_AUTOROAD),
874 Hotkey('4', "demolish", WID_ROT_DEMOLISH),
875 Hotkey('5', "depot", WID_ROT_DEPOT),
876 Hotkey('6', "bus_station", WID_ROT_BUS_STATION),
877 Hotkey('7', "truck_station", WID_ROT_TRUCK_STATION),
878 Hotkey('8', "oneway", WID_ROT_ONE_WAY),
879 Hotkey('9', "waypoint", WID_ROT_BUILD_WAYPOINT),
880 Hotkey('B', "bridge", WID_ROT_BUILD_BRIDGE),
881 Hotkey('T', "tunnel", WID_ROT_BUILD_TUNNEL),
882 Hotkey('R', "remove", WID_ROT_REMOVE),
883 Hotkey('C', "convert", WID_ROT_CONVERT_ROAD),
884 }, RoadToolbarGlobalHotkeys};
885
886 static inline HotkeyList tram_hotkeys{"tramtoolbar", {
887 Hotkey('1', "build_x", WID_ROT_ROAD_X),
888 Hotkey('2', "build_y", WID_ROT_ROAD_Y),
889 Hotkey('3', "autoroad", WID_ROT_AUTOROAD),
890 Hotkey('4', "demolish", WID_ROT_DEMOLISH),
891 Hotkey('5', "depot", WID_ROT_DEPOT),
892 Hotkey('6', "bus_station", WID_ROT_BUS_STATION),
893 Hotkey('7', "truck_station", WID_ROT_TRUCK_STATION),
894 Hotkey('9', "waypoint", WID_ROT_BUILD_WAYPOINT),
895 Hotkey('B', "bridge", WID_ROT_BUILD_BRIDGE),
896 Hotkey('T', "tunnel", WID_ROT_BUILD_TUNNEL),
897 Hotkey('R', "remove", WID_ROT_REMOVE),
898 Hotkey('C', "convert", WID_ROT_CONVERT_ROAD),
899 }, TramToolbarGlobalHotkeys};
900};
901
902static constexpr NWidgetPart _nested_build_road_widgets[] = {
904 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
905 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetTextStyle(TC_WHITE),
906 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
907 EndContainer(),
909 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_X),
910 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_ROAD_X_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION),
911 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_Y),
912 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_ROAD_Y_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION),
913 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_AUTOROAD),
914 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_AUTOROAD, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD),
915 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEMOLISH),
916 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
917 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEPOT),
918 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_ROAD_DEPOT, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT),
919 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_WAYPOINT),
920 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_WAYPOINT, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD_TO_WAYPOINT),
921 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUS_STATION),
922 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_BUS_STATION, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION),
923 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_TRUCK_STATION),
924 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_TRUCK_BAY, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY),
925 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
926 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ONE_WAY),
927 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_ROAD_ONE_WAY, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD),
928 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE),
929 SetFill(0, 1), SetMinimalSize(43, 22), SetSpriteTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE),
930 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL),
931 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL),
932 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_REMOVE),
933 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD),
934 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_CONVERT_ROAD),
935 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_CONVERT_ROAD, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD),
936 EndContainer(),
937};
938
939static WindowDesc _build_road_desc(
940 WDP_ALIGN_TOOLBAR, "toolbar_road", 0, 0,
943 _nested_build_road_widgets,
944 &BuildRoadToolbarWindow::road_hotkeys
945);
946
947static constexpr NWidgetPart _nested_build_tramway_widgets[] = {
949 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
950 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetTextStyle(TC_WHITE),
951 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
952 EndContainer(),
954 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_X),
955 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_TRAMWAY_X_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION),
956 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_Y),
957 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_TRAMWAY_Y_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION),
958 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_AUTOROAD),
959 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_AUTOTRAM, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM),
960 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEMOLISH),
961 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
962 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEPOT),
963 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_ROAD_DEPOT, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT),
964 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_WAYPOINT),
965 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_WAYPOINT, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM_TO_WAYPOINT),
966 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUS_STATION),
967 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_BUS_STATION, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION),
968 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_TRUCK_STATION),
969 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_TRUCK_BAY, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION),
970 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
971 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE),
972 SetFill(0, 1), SetMinimalSize(43, 22), SetSpriteTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE),
973 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL),
974 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL),
975 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_REMOVE),
976 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS),
977 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_CONVERT_ROAD),
978 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_CONVERT_ROAD, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM),
979 EndContainer(),
980};
981
982static WindowDesc _build_tramway_desc(
983 WDP_ALIGN_TOOLBAR, "toolbar_tramway", 0, 0,
986 _nested_build_tramway_widgets,
987 &BuildRoadToolbarWindow::tram_hotkeys
988);
989
998{
999 if (!Company::IsValidID(_local_company)) return nullptr;
1000 if (!ValParamRoadType(roadtype)) return nullptr;
1001
1003 _cur_roadtype = roadtype;
1004
1005 return AllocateWindowDescFront<BuildRoadToolbarWindow>(RoadTypeIsRoad(_cur_roadtype) ? _build_road_desc : _build_tramway_desc, TRANSPORT_ROAD);
1006}
1007
1008static constexpr NWidgetPart _nested_build_road_scen_widgets[] = {
1010 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1011 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetTextStyle(TC_WHITE),
1012 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
1013 EndContainer(),
1015 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_X),
1016 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_ROAD_X_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION),
1017 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_Y),
1018 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_ROAD_Y_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION),
1019 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_AUTOROAD),
1020 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_AUTOROAD, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD),
1021 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEMOLISH),
1022 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
1023 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
1024 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ONE_WAY),
1025 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_ROAD_ONE_WAY, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD),
1026 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE),
1027 SetFill(0, 1), SetMinimalSize(43, 22), SetSpriteTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE),
1028 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL),
1029 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL),
1030 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_REMOVE),
1031 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD),
1032 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_CONVERT_ROAD),
1033 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_CONVERT_ROAD, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD),
1034 EndContainer(),
1035};
1036
1037static WindowDesc _build_road_scen_desc(
1038 WDP_AUTO, "toolbar_road_scen", 0, 0,
1041 _nested_build_road_scen_widgets,
1042 &BuildRoadToolbarWindow::road_hotkeys
1043);
1044
1045static constexpr NWidgetPart _nested_build_tramway_scen_widgets[] = {
1047 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1048 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetTextStyle(TC_WHITE),
1049 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
1050 EndContainer(),
1052 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_X),
1053 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_TRAMWAY_X_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION),
1054 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_Y),
1055 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_TRAMWAY_Y_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION),
1056 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_AUTOROAD),
1057 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_AUTOTRAM, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM),
1058 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEMOLISH),
1059 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
1060 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
1061 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE),
1062 SetFill(0, 1), SetMinimalSize(43, 22), SetSpriteTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE),
1063 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL),
1064 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL),
1065 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_REMOVE),
1066 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS),
1067 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_CONVERT_ROAD),
1068 SetFill(0, 1), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_CONVERT_ROAD, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM),
1069 EndContainer(),
1070};
1071
1072static WindowDesc _build_tramway_scen_desc(
1073 WDP_AUTO, "toolbar_tram_scen", 0, 0,
1076 _nested_build_tramway_scen_widgets,
1077 &BuildRoadToolbarWindow::tram_hotkeys
1078);
1079
1085{
1087 _cur_roadtype = roadtype;
1088
1089 return AllocateWindowDescFront<BuildRoadToolbarWindow>(RoadTypeIsRoad(_cur_roadtype) ? _build_road_scen_desc : _build_tramway_scen_desc, TRANSPORT_ROAD);
1090}
1091
1094 {
1095 this->CreateNestedTree();
1096
1097 this->LowerWidget(WID_BROD_DEPOT_NE + _road_depot_orientation);
1098 if (RoadTypeIsTram(_cur_roadtype)) {
1100 for (WidgetID i = WID_BROD_DEPOT_NE; i <= WID_BROD_DEPOT_NW; i++) {
1102 }
1103 }
1104
1106 }
1107
1109 {
1110 if (!IsInsideMM(widget, WID_BROD_DEPOT_NE, WID_BROD_DEPOT_NW + 1)) return;
1111
1114 }
1115
1116 void DrawWidget(const Rect &r, WidgetID widget) const override
1117 {
1118 if (!IsInsideMM(widget, WID_BROD_DEPOT_NE, WID_BROD_DEPOT_NW + 1)) return;
1119
1122 if (FillDrawPixelInfo(&tmp_dpi, ir)) {
1124 int x = (ir.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31);
1125 int y = (ir.Height() + ScaleSpriteTrad(48)) / 2 - ScaleSpriteTrad(31);
1126 DrawRoadDepotSprite(x, y, (DiagDirection)(widget - WID_BROD_DEPOT_NE + DIAGDIR_NE), _cur_roadtype);
1127 }
1128 }
1129
1130 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1131 {
1132 switch (widget) {
1133 case WID_BROD_DEPOT_NW:
1134 case WID_BROD_DEPOT_NE:
1135 case WID_BROD_DEPOT_SW:
1136 case WID_BROD_DEPOT_SE:
1137 this->RaiseWidget(WID_BROD_DEPOT_NE + _road_depot_orientation);
1138 _road_depot_orientation = (DiagDirection)(widget - WID_BROD_DEPOT_NE);
1139 this->LowerWidget(WID_BROD_DEPOT_NE + _road_depot_orientation);
1141 this->SetDirty();
1142 break;
1143
1144 default:
1145 break;
1146 }
1147 }
1148};
1149
1150static constexpr NWidgetPart _nested_build_road_depot_widgets[] = {
1152 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1153 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROD_CAPTION), SetStringTip(STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1154 EndContainer(),
1155 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
1158 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROD_DEPOT_NW), SetFill(0, 0), SetToolTip(STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
1159 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROD_DEPOT_SW), SetFill(0, 0), SetToolTip(STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
1160 EndContainer(),
1162 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROD_DEPOT_NE), SetFill(0, 0), SetToolTip(STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
1163 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROD_DEPOT_SE), SetFill(0, 0), SetToolTip(STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
1164 EndContainer(),
1165 EndContainer(),
1166 EndContainer(),
1167};
1168
1169static WindowDesc _build_road_depot_desc(
1170 WDP_AUTO, nullptr, 0, 0,
1173 _nested_build_road_depot_widgets
1174);
1175
1176static void ShowRoadDepotPicker(Window *parent)
1177{
1178 new BuildRoadDepotWindow(_build_road_depot_desc, parent);
1179}
1180
1181template <RoadStopType roadstoptype>
1183public:
1185
1186 GrfSpecFeature GetFeature() const override { return GSF_ROADSTOPS; }
1187
1188 StringID GetClassTooltip() const override;
1189 StringID GetTypeTooltip() const override;
1190
1191 bool IsActive() const override
1192 {
1193 for (const auto &cls : RoadStopClass::Classes()) {
1194 if (IsWaypointClass(cls)) continue;
1195 for (const auto *spec : cls.Specs()) {
1196 if (spec == nullptr) continue;
1197 if (roadstoptype == RoadStopType::Truck && spec->stop_type != ROADSTOPTYPE_FREIGHT && spec->stop_type != ROADSTOPTYPE_ALL) continue;
1198 if (roadstoptype == RoadStopType::Bus && spec->stop_type != ROADSTOPTYPE_PASSENGER && spec->stop_type != ROADSTOPTYPE_ALL) continue;
1199 return true;
1200 }
1201 }
1202 return false;
1203 }
1204
1205 static bool IsClassChoice(const RoadStopClass &cls)
1206 {
1207 return !IsWaypointClass(cls) && GetIfClassHasNewStopsByType(&cls, roadstoptype, _cur_roadtype);
1208 }
1209
1210 bool HasClassChoice() const override
1211 {
1212 return std::ranges::count_if(RoadStopClass::Classes(), IsClassChoice);
1213 }
1214
1215 int GetSelectedClass() const override { return _roadstop_gui.sel_class; }
1216 void SetSelectedClass(int id) const override { _roadstop_gui.sel_class = this->GetClassIndex(id); }
1217
1218 StringID GetClassName(int id) const override
1219 {
1220 const auto *rsc = this->GetClass(id);
1221 if (!IsClassChoice(*rsc)) return INVALID_STRING_ID;
1222 return rsc->name;
1223 }
1224
1225 int GetSelectedType() const override { return _roadstop_gui.sel_type; }
1226 void SetSelectedType(int id) const override { _roadstop_gui.sel_type = id; }
1227
1228 StringID GetTypeName(int cls_id, int id) const override
1229 {
1230 const auto *spec = this->GetSpec(cls_id, id);
1231 if (!IsRoadStopEverAvailable(spec, roadstoptype == RoadStopType::Bus ? StationType::Bus : StationType::Truck)) return INVALID_STRING_ID;
1232 return (spec == nullptr) ? STR_STATION_CLASS_DFLT_ROADSTOP : spec->name;
1233 }
1234
1235 std::span<const BadgeID> GetTypeBadges(int cls_id, int id) const override
1236 {
1237 const auto *spec = this->GetSpec(cls_id, id);
1238 if (!IsRoadStopEverAvailable(spec, roadstoptype == RoadStopType::Bus ? StationType::Bus : StationType::Truck)) return {};
1239 if (spec == nullptr) return {};
1240 return spec->badges;
1241 }
1242
1243 bool IsTypeAvailable(int cls_id, int id) const override
1244 {
1245 const auto *spec = this->GetSpec(cls_id, id);
1246 return IsRoadStopAvailable(spec, roadstoptype == RoadStopType::Bus ? StationType::Bus : StationType::Truck);
1247 }
1248
1249 void DrawType(int x, int y, int cls_id, int id) const override
1250 {
1251 const auto *spec = this->GetSpec(cls_id, id);
1252 if (spec == nullptr) {
1253 StationPickerDrawSprite(x, y, roadstoptype == RoadStopType::Bus ? StationType::Bus : StationType::Truck, INVALID_RAILTYPE, _cur_roadtype, _roadstop_gui.orientation);
1254 } else {
1255 DiagDirection orientation = _roadstop_gui.orientation;
1256 if (orientation < DIAGDIR_END && spec->flags.Test(RoadStopSpecFlag::DriveThroughOnly)) orientation = DIAGDIR_END;
1257 DrawRoadStopTile(x, y, _cur_roadtype, spec, roadstoptype == RoadStopType::Bus ? StationType::Bus : StationType::Truck, (uint8_t)orientation);
1258 }
1259 }
1260
1261 void FillUsedItems(std::set<PickerItem> &items) override
1262 {
1263 for (const Station *st : Station::Iterate()) {
1264 if (st->owner != _local_company) continue;
1265 if (roadstoptype == RoadStopType::Truck && !st->facilities.Test(StationFacility::TruckStop)) continue;
1266 if (roadstoptype == RoadStopType::Bus && !st->facilities.Test(StationFacility::BusStop)) continue;
1267 items.insert({0, 0, ROADSTOP_CLASS_DFLT, 0}); // We would need to scan the map to find out if default is used.
1268 for (const auto &sm : st->roadstop_speclist) {
1269 if (sm.spec == nullptr) continue;
1270 if (roadstoptype == RoadStopType::Truck && sm.spec->stop_type != ROADSTOPTYPE_FREIGHT && sm.spec->stop_type != ROADSTOPTYPE_ALL) continue;
1271 if (roadstoptype == RoadStopType::Bus && sm.spec->stop_type != ROADSTOPTYPE_PASSENGER && sm.spec->stop_type != ROADSTOPTYPE_ALL) continue;
1272 items.insert({sm.grfid, sm.localidx, sm.spec->class_index, sm.spec->index});
1273 }
1274 }
1275 }
1276};
1277
1278template <> StringID RoadStopPickerCallbacks<RoadStopType::Bus>::GetClassTooltip() const { return STR_PICKER_ROADSTOP_BUS_CLASS_TOOLTIP; }
1279template <> StringID RoadStopPickerCallbacks<RoadStopType::Bus>::GetTypeTooltip() const { return STR_PICKER_ROADSTOP_BUS_TYPE_TOOLTIP; }
1280
1281template <> StringID RoadStopPickerCallbacks<RoadStopType::Truck>::GetClassTooltip() const { return STR_PICKER_ROADSTOP_TRUCK_CLASS_TOOLTIP; }
1282template <> StringID RoadStopPickerCallbacks<RoadStopType::Truck>::GetTypeTooltip() const { return STR_PICKER_ROADSTOP_TRUCK_TYPE_TOOLTIP; }
1283
1284static RoadStopPickerCallbacks<RoadStopType::Bus> _bus_callback_instance("fav_passenger_roadstops");
1285static RoadStopPickerCallbacks<RoadStopType::Truck> _truck_callback_instance("fav_freight_roadstops");
1286
1287static PickerCallbacks &GetRoadStopPickerCallbacks(RoadStopType rs)
1288{
1289 return rs == RoadStopType::Bus ? static_cast<PickerCallbacks &>(_bus_callback_instance) : static_cast<PickerCallbacks &>(_truck_callback_instance);
1290}
1291
1293private:
1295
1296 void CheckOrientationValid()
1297 {
1298 const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui.sel_class)->GetSpec(_roadstop_gui.sel_type);
1299
1300 /* Raise and lower to ensure the correct widget is lowered after changing displayed orientation plane. */
1301 if (RoadTypeIsRoad(_cur_roadtype)) {
1302 this->RaiseWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
1303 this->GetWidget<NWidgetStacked>(WID_BROS_AVAILABLE_ORIENTATIONS)->SetDisplayedPlane((spec != nullptr && spec->flags.Test(RoadStopSpecFlag::DriveThroughOnly)) ? 1 : 0);
1304 this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
1305 }
1306
1307 if (_roadstop_gui.orientation >= DIAGDIR_END) return;
1308
1309 if (spec != nullptr && spec->flags.Test(RoadStopSpecFlag::DriveThroughOnly)) {
1310 this->RaiseWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
1311 _roadstop_gui.orientation = DIAGDIR_END;
1312 this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
1313 this->SetDirty();
1315 }
1316 }
1317
1318public:
1319 BuildRoadStationWindow(WindowDesc &desc, Window *parent, RoadStopType rs) : PickerWindow(desc, parent, TRANSPORT_ROAD, GetRoadStopPickerCallbacks(rs))
1320 {
1322
1323 /* Trams don't have non-drivethrough stations */
1324 if (RoadTypeIsTram(_cur_roadtype) && _roadstop_gui.orientation < DIAGDIR_END) {
1325 _roadstop_gui.orientation = DIAGDIR_END;
1326 }
1327 this->ConstructWindow();
1328
1329 const RoadTypeInfo *rti = GetRoadTypeInfo(_cur_roadtype);
1331
1332 for (WidgetID i = RoadTypeIsTram(_cur_roadtype) ? WID_BROS_STATION_X : WID_BROS_STATION_NE; i < WID_BROS_LT_OFF; i++) {
1333 this->GetWidget<NWidgetCore>(i)->SetToolTip(rti->strings.picker_tooltip[to_underlying(rs)]);
1334 }
1335
1336 this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
1337 this->LowerWidget(WID_BROS_LT_OFF + _settings_client.gui.station_show_coverage);
1338
1340 }
1341
1342 void Close([[maybe_unused]] int data = 0) override
1343 {
1345 this->PickerWindow::Close();
1346 }
1347
1348 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
1349 {
1351
1352 if (gui_scope) {
1353 this->CheckOrientationValid();
1354 }
1355 }
1356
1357 void OnPaint() override
1358 {
1359 const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui.sel_class)->GetSpec(_roadstop_gui.sel_type);
1360
1361 this->DrawWidgets();
1362
1365 SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
1366 } else {
1367 SetTileSelectSize(1, 1);
1368 }
1369
1370 if (this->IsShaded()) return;
1371
1372 /* 'Accepts' and 'Supplies' texts. */
1374 Rect r = this->GetWidget<NWidgetBase>(WID_BROS_ACCEPTANCE)->GetCurrentRect();
1375 const int bottom = r.bottom;
1376 r.bottom = INT_MAX; // Allow overflow as we want to know the required height.
1377 if (spec != nullptr) r.top = DrawBadgeNameList(r, spec->badges, GSF_ROADSTOPS);
1379 r.top = DrawStationCoverageAreaText(r, sct, rad, true);
1380 /* Resize background if the window is too small.
1381 * Never make the window smaller to avoid oscillating if the size change affects the acceptance.
1382 * (This is the case, if making the window bigger moves the mouse into the window.) */
1383 if (r.top > bottom) {
1384 this->coverage_height += r.top - bottom;
1385 this->ReInit();
1386 }
1387 }
1388
1390 {
1391 switch (widget) {
1396 case WID_BROS_STATION_X:
1397 case WID_BROS_STATION_Y:
1400 break;
1401
1403 size.height = this->coverage_height;
1404 break;
1405
1406 default:
1407 this->PickerWindow::UpdateWidgetSize(widget, size, padding, fill, resize);
1408 break;
1409 }
1410 }
1411
1416 {
1417 switch (window_class) {
1418 case WC_BUS_STATION: return StationType::Bus;
1419 case WC_TRUCK_STATION: return StationType::Truck;
1420 default: NOT_REACHED();
1421 }
1422 }
1423
1424 void DrawWidget(const Rect &r, WidgetID widget) const override
1425 {
1426 switch (widget) {
1431 case WID_BROS_STATION_X:
1432 case WID_BROS_STATION_Y: {
1434 const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui.sel_class)->GetSpec(_roadstop_gui.sel_type);
1437 if (FillDrawPixelInfo(&tmp_dpi, ir)) {
1439 int x = (ir.Width() - ScaleSpriteTrad(PREVIEW_WIDTH)) / 2 + ScaleSpriteTrad(PREVIEW_LEFT);
1440 int y = (ir.Height() + ScaleSpriteTrad(PREVIEW_HEIGHT)) / 2 - ScaleSpriteTrad(PREVIEW_BOTTOM);
1441 if (spec == nullptr) {
1442 StationPickerDrawSprite(x, y, st, INVALID_RAILTYPE, _cur_roadtype, widget - WID_BROS_STATION_NE);
1443 } else {
1444 DrawRoadStopTile(x, y, _cur_roadtype, spec, st, widget - WID_BROS_STATION_NE);
1445 }
1446 }
1447 break;
1448 }
1449
1450 default:
1451 this->PickerWindow::DrawWidget(r, widget);
1452 break;
1453 }
1454 }
1455
1456 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1457 {
1458 switch (widget) {
1463 case WID_BROS_STATION_X:
1464 case WID_BROS_STATION_Y:
1465 if (widget < WID_BROS_STATION_X) {
1466 const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui.sel_class)->GetSpec(_roadstop_gui.sel_type);
1467 if (spec != nullptr && spec->flags.Test(RoadStopSpecFlag::DriveThroughOnly)) return;
1468 }
1469 this->RaiseWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
1470 _roadstop_gui.orientation = (DiagDirection)(widget - WID_BROS_STATION_NE);
1471 this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
1473 this->SetDirty();
1475 break;
1476
1477 case WID_BROS_LT_OFF:
1478 case WID_BROS_LT_ON:
1479 this->RaiseWidget(_settings_client.gui.station_show_coverage + WID_BROS_LT_OFF);
1481 this->LowerWidget(_settings_client.gui.station_show_coverage + WID_BROS_LT_OFF);
1483 this->SetDirty();
1484 SetViewportCatchmentStation(nullptr, true);
1485 break;
1486
1487 default:
1488 this->PickerWindow::OnClick(pt, widget, click_count);
1489 break;
1490 }
1491 }
1492
1493 void OnRealtimeTick([[maybe_unused]] uint delta_ms) override
1494 {
1496 }
1497
1498 static inline HotkeyList road_hotkeys{"buildroadstop", {
1499 Hotkey('F', "focus_filter_box", PCWHK_FOCUS_FILTER_BOX),
1500 }};
1501
1502 static inline HotkeyList tram_hotkeys{"buildtramstop", {
1503 Hotkey('F', "focus_filter_box", PCWHK_FOCUS_FILTER_BOX),
1504 }};
1505};
1506
1510 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1511 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROS_CAPTION),
1512 NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
1513 NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN),
1514 EndContainer(),
1518 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
1521 /* 6-orientation plane. */
1525 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NW), SetFill(0, 0), EndContainer(),
1526 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NE), SetFill(0, 0), EndContainer(),
1527 EndContainer(),
1528 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetFill(0, 0), EndContainer(),
1529 EndContainer(),
1532 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SW), SetFill(0, 0), EndContainer(),
1533 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SE), SetFill(0, 0), EndContainer(),
1534 EndContainer(),
1535 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetFill(0, 0), EndContainer(),
1536 EndContainer(),
1537 EndContainer(),
1538 /* 2-orientation plane. */
1541 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetFill(0, 0), EndContainer(),
1542 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetFill(0, 0), EndContainer(),
1543 EndContainer(),
1544 EndContainer(),
1545 EndContainer(),
1546 NWidget(WWT_LABEL, INVALID_COLOUR), SetStringTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE), SetFill(1, 0),
1548 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_OFF), SetMinimalSize(60, 12),
1549 SetStringTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
1550 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_ON), SetMinimalSize(60, 12),
1551 SetStringTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
1552 EndContainer(),
1553 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BROS_ACCEPTANCE), SetFill(1, 1), SetResize(1, 0), SetMinimalTextLines(2, 0),
1554 EndContainer(),
1555 EndContainer(),
1556 EndContainer(),
1558 EndContainer(),
1559};
1560
1561static WindowDesc _road_station_picker_desc(
1562 WDP_AUTO, "build_station_road", 0, 0,
1566 &BuildRoadStationWindow::road_hotkeys
1567);
1568
1572 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1573 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROS_CAPTION),
1574 NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
1575 NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN),
1576 EndContainer(),
1580 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
1583 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetFill(0, 0), EndContainer(),
1584 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetFill(0, 0), EndContainer(),
1585 EndContainer(),
1586 NWidget(WWT_LABEL, INVALID_COLOUR), SetStringTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE), SetFill(1, 0),
1588 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_OFF), SetMinimalSize(60, 12),
1589 SetStringTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
1590 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_ON), SetMinimalSize(60, 12),
1591 SetStringTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
1592 EndContainer(),
1593 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BROS_ACCEPTANCE), SetFill(1, 1), SetResize(1, 0), SetMinimalTextLines(2, 0),
1594 EndContainer(),
1595 EndContainer(),
1596 EndContainer(),
1598 EndContainer(),
1599};
1600
1601static WindowDesc _tram_station_picker_desc(
1602 WDP_AUTO, "build_station_tram", 0, 0,
1606 &BuildRoadStationWindow::tram_hotkeys
1607);
1608
1609static void ShowRVStationPicker(Window *parent, RoadStopType rs)
1610{
1611 new BuildRoadStationWindow(RoadTypeIsRoad(_cur_roadtype) ? _road_station_picker_desc : _tram_station_picker_desc, parent, rs);
1612}
1613
1615public:
1617
1618 GrfSpecFeature GetFeature() const override { return GSF_ROADSTOPS; }
1619
1620 StringID GetClassTooltip() const override { return STR_PICKER_WAYPOINT_CLASS_TOOLTIP; }
1621 StringID GetTypeTooltip() const override { return STR_PICKER_WAYPOINT_TYPE_TOOLTIP; }
1622
1623 bool IsActive() const override
1624 {
1625 for (const auto &cls : RoadStopClass::Classes()) {
1626 if (!IsWaypointClass(cls)) continue;
1627 for (const auto *spec : cls.Specs()) {
1628 if (spec != nullptr) return true;
1629 }
1630 }
1631 return false;
1632 }
1633
1634 bool HasClassChoice() const override
1635 {
1636 return std::ranges::count_if(RoadStopClass::Classes(), IsWaypointClass) > 1;
1637 }
1638
1639 void Close(int) override { ResetObjectToPlace(); }
1640 int GetSelectedClass() const override { return _waypoint_gui.sel_class; }
1641 void SetSelectedClass(int id) const override { _waypoint_gui.sel_class = this->GetClassIndex(id); }
1642
1643 StringID GetClassName(int id) const override
1644 {
1645 const auto *sc = GetClass(id);
1646 if (!IsWaypointClass(*sc)) return INVALID_STRING_ID;
1647 return sc->name;
1648 }
1649
1650 int GetSelectedType() const override { return _waypoint_gui.sel_type; }
1651 void SetSelectedType(int id) const override { _waypoint_gui.sel_type = id; }
1652
1653 StringID GetTypeName(int cls_id, int id) const override
1654 {
1655 const auto *spec = this->GetSpec(cls_id, id);
1656 return (spec == nullptr) ? STR_STATION_CLASS_WAYP_WAYPOINT : spec->name;
1657 }
1658
1659 std::span<const BadgeID> GetTypeBadges(int cls_id, int id) const override
1660 {
1661 const auto *spec = this->GetSpec(cls_id, id);
1662 if (spec == nullptr) return {};
1663 return spec->badges;
1664 }
1665
1666 bool IsTypeAvailable(int cls_id, int id) const override
1667 {
1668 return IsRoadStopAvailable(this->GetSpec(cls_id, id), StationType::RoadWaypoint);
1669 }
1670
1671 void DrawType(int x, int y, int cls_id, int id) const override
1672 {
1673 const auto *spec = this->GetSpec(cls_id, id);
1674 if (spec == nullptr) {
1675 StationPickerDrawSprite(x, y, StationType::RoadWaypoint, INVALID_RAILTYPE, _cur_roadtype, RSV_DRIVE_THROUGH_X);
1676 } else {
1677 DrawRoadStopTile(x, y, _cur_roadtype, spec, StationType::RoadWaypoint, RSV_DRIVE_THROUGH_X);
1678 }
1679 }
1680
1681 void FillUsedItems(std::set<PickerItem> &items) override
1682 {
1683 for (const Waypoint *wp : Waypoint::Iterate()) {
1684 if (wp->owner != _local_company || !HasBit(wp->waypoint_flags, WPF_ROAD)) continue;
1685 items.insert({0, 0, ROADSTOP_CLASS_WAYP, 0}); // We would need to scan the map to find out if default is used.
1686 for (const auto &sm : wp->roadstop_speclist) {
1687 if (sm.spec == nullptr) continue;
1688 items.insert({sm.grfid, sm.localidx, sm.spec->class_index, sm.spec->index});
1689 }
1690 }
1691 }
1692
1693 static RoadWaypointPickerCallbacks instance;
1694};
1695/* static */ RoadWaypointPickerCallbacks RoadWaypointPickerCallbacks::instance;
1696
1698 BuildRoadWaypointWindow(WindowDesc &desc, Window *parent) : PickerWindow(desc, parent, TRANSPORT_ROAD, RoadWaypointPickerCallbacks::instance)
1699 {
1700 this->ConstructWindow();
1701 }
1702
1703 static inline HotkeyList hotkeys{"buildroadwaypoint", {
1704 Hotkey('F', "focus_filter_box", PCWHK_FOCUS_FILTER_BOX),
1705 }};
1706};
1707
1711 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1712 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_WAYPOINT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1713 NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
1714 NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN),
1715 EndContainer(),
1719 EndContainer(),
1720};
1721
1722static WindowDesc _build_road_waypoint_desc(
1723 WDP_AUTO, "build_road_waypoint", 0, 0,
1727 &BuildRoadWaypointWindow::hotkeys
1728);
1729
1730static void ShowBuildRoadWaypointPicker(Window *parent)
1731{
1732 if (!RoadWaypointPickerCallbacks::instance.IsActive()) return;
1733 new BuildRoadWaypointWindow(_build_road_waypoint_desc, parent);
1734}
1735
1736void InitializeRoadGui()
1737{
1738 _road_depot_orientation = DIAGDIR_NW;
1739 _roadstop_gui.orientation = DIAGDIR_NW;
1742}
1743
1748{
1750 if (w != nullptr) w->ModifyRoadType(_cur_roadtype);
1751}
1752
1753DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement, bool all_option)
1754{
1755 RoadTypes used_roadtypes;
1756 RoadTypes avail_roadtypes;
1757
1759
1760 /* Find the used roadtypes. */
1761 if (for_replacement) {
1762 avail_roadtypes = GetCompanyRoadTypes(c->index, false);
1763 used_roadtypes = GetRoadTypes(false);
1764 } else {
1765 avail_roadtypes = c->avail_roadtypes;
1766 used_roadtypes = GetRoadTypes(true);
1767 }
1768
1769 /* Filter listed road types */
1770 if (!HasBit(rtts, RTT_ROAD)) used_roadtypes &= _roadtypes_type;
1771 if (!HasBit(rtts, RTT_TRAM)) used_roadtypes &= ~_roadtypes_type;
1772
1773 DropDownList list;
1774
1775 if (all_option) {
1776 list.push_back(MakeDropDownListStringItem(STR_REPLACE_ALL_ROADTYPE, INVALID_ROADTYPE));
1777 }
1778
1779 Dimension d = { 0, 0 };
1780 /* Get largest icon size, to ensure text is aligned on each menu item. */
1781 if (!for_replacement) {
1782 for (const auto &rt : _sorted_roadtypes) {
1783 if (!HasBit(used_roadtypes, rt)) continue;
1784 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
1786 }
1787 }
1788
1789 /* Shared list so that each item can take ownership. */
1790 auto badge_class_list = std::make_shared<GUIBadgeClasses>(GSF_ROADTYPES);
1791
1792 for (const auto &rt : _sorted_roadtypes) {
1793 /* If it's not used ever, don't show it to the user. */
1794 if (!HasBit(used_roadtypes, rt)) continue;
1795
1796 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
1797
1798 if (for_replacement) {
1799 list.push_back(MakeDropDownListBadgeItem(badge_class_list, rti->badges, GSF_ROADTYPES, rti->introduction_date, GetString(rti->strings.replace_text), rt, !HasBit(avail_roadtypes, rt)));
1800 } else {
1801 std::string str = rti->max_speed > 0
1802 ? GetString(STR_TOOLBAR_RAILTYPE_VELOCITY, rti->strings.menu_text, rti->max_speed / 2)
1803 : GetString(rti->strings.menu_text);
1804 list.push_back(MakeDropDownListBadgeIconItem(badge_class_list, rti->badges, GSF_ROADTYPES, rti->introduction_date, d, rti->gui_sprites.build_x_road, PAL_NONE, std::move(str), rt, !HasBit(avail_roadtypes, rt)));
1805 }
1806 }
1807
1808 if (list.empty()) {
1809 /* Empty dropdowns are not allowed */
1810 list.push_back(MakeDropDownListStringItem(STR_NONE, INVALID_ROADTYPE, true));
1811 }
1812
1813 return list;
1814}
1815
1816DropDownList GetScenRoadTypeDropDownList(RoadTramTypes rtts)
1817{
1818 RoadTypes avail_roadtypes = GetRoadTypes(false);
1819 avail_roadtypes = AddDateIntroducedRoadTypes(avail_roadtypes, TimerGameCalendar::date);
1820 RoadTypes used_roadtypes = GetRoadTypes(true);
1821
1822 /* Filter listed road types */
1823 if (!HasBit(rtts, RTT_ROAD)) used_roadtypes &= _roadtypes_type;
1824 if (!HasBit(rtts, RTT_TRAM)) used_roadtypes &= ~_roadtypes_type;
1825
1826 DropDownList list;
1827
1828 /* If it's not used ever, don't show it to the user. */
1829 Dimension d = { 0, 0 };
1830 for (const auto &rt : _sorted_roadtypes) {
1831 if (!HasBit(used_roadtypes, rt)) continue;
1832 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
1834 }
1835
1836 /* Shared list so that each item can take ownership. */
1837 auto badge_class_list = std::make_shared<GUIBadgeClasses>(GSF_ROADTYPES);
1838
1839 for (const auto &rt : _sorted_roadtypes) {
1840 if (!HasBit(used_roadtypes, rt)) continue;
1841
1842 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
1843
1844 std::string str = rti->max_speed > 0
1845 ? GetString(STR_TOOLBAR_RAILTYPE_VELOCITY, rti->strings.menu_text, rti->max_speed / 2)
1846 : GetString(rti->strings.menu_text);
1847 list.push_back(MakeDropDownListBadgeIconItem(badge_class_list, rti->badges, GSF_ROADTYPES, rti->introduction_date, d, rti->gui_sprites.build_x_road, PAL_NONE, std::move(str), rt, !HasBit(avail_roadtypes, rt)));
1848 }
1849
1850 if (list.empty()) {
1851 /* Empty dropdowns are not allowed */
1852 list.push_back(MakeDropDownListStringItem(STR_NONE, -1, true));
1853 }
1854
1855 return list;
1856}
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, uint8_t road_rail_type)
Prepare the data for the build a bridge window.
bool IsBridgeTile(Tile t)
checks if there is a bridge on this tile
Definition bridge_map.h:35
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Common return value for all commands.
bool Succeeded() const
Did this command succeed?
bool Failed() const
Did this command fail?
Struct containing information relating to NewGRF classes for stations and airports.
static std::span< NewGRFClass< Tspec, Tindex, Tmax > const > Classes()
Get read-only span of all classes of this type.
static NewGRFClass * Get(Tindex class_index)
Get a particular class.
static uint GetClassCount()
Get the number of allocated classes.
const Tspec * GetSpec(uint index) const
Get a spec from the class at a given index.
Helper for PickerCallbacks when the class system is based on NewGRFClass.
Definition picker_gui.h:104
Class for PickerClassWindow to collect information and retain state.
Definition picker_gui.h:38
const std::string ini_group
Ini Group for saving favourites.
Definition picker_gui.h:95
Base class for windows opened from a toolbar.
Definition window_gui.h:982
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
static const int PREVIEW_LEFT
Offset from left edge to draw preview.
Definition picker_gui.h:173
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
@ PCWHK_FOCUS_FILTER_BOX
Focus the edit box for editing the filter string.
Definition picker_gui.h:194
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
static const int PREVIEW_WIDTH
Width of each preview button.
Definition picker_gui.h:171
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
static const int PREVIEW_BOTTOM
Offset from bottom edge to draw preview.
Definition picker_gui.h:174
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.
static const int PREVIEW_HEIGHT
Height of each preview button.
Definition picker_gui.h:172
void SetSelectedType(int id) const override
Set the selected type.
bool HasClassChoice() const override
Are there multiple classes to chose from?
StringID GetClassTooltip() const override
Get the tooltip string for the class list.
StringID GetClassName(int id) const override
Get the name of a class.
void FillUsedItems(std::set< PickerItem > &items) override
Fill a set with all items that are used by the current player.
void SetSelectedClass(int id) const override
Set the selected class.
void DrawType(int x, int y, int cls_id, int id) const override
Draw preview image of an item.
int GetSelectedClass() const override
Get the index of the selected class.
std::span< const BadgeID > GetTypeBadges(int cls_id, int id) const override
Get the item of a type.
StringID GetTypeName(int cls_id, int id) const override
Get the item of a type.
bool IsActive() const override
Should picker class/type selection be enabled?
int GetSelectedType() const override
Get the selected type.
bool IsTypeAvailable(int cls_id, int id) const override
Test if an item is currently buildable.
StringID GetTypeTooltip() const override
Get the tooltip string for the type grid.
StringID menu_text
Name of this rail type in the main toolbar dropdown.
Definition road.h:96
StringID replace_text
Text used in the autoreplace GUI.
Definition road.h:98
StringID picker_title[2]
Title for the station picker for bus or truck stations.
Definition road.h:108
CursorID autoroad
Cursor for autorail tool.
Definition road.h:87
TimerGameCalendar::Date introduction_date
Introduction date.
Definition road.h:157
StringID picker_tooltip[2]
Tooltip for the station picker for bus or truck stations.
Definition road.h:109
StringID err_build_road
Building a normal piece of road.
Definition road.h:101
StringID err_remove_road
Removing a normal piece of road.
Definition road.h:102
CursorID depot
Cursor for building a depot.
Definition road.h:88
CursorID road_nwse
Cursor for building rail in Y direction.
Definition road.h:86
uint16_t max_speed
Maximum speed for vehicles travelling on this road type.
Definition road.h:133
StringID toolbar_caption
Caption in the construction toolbar GUI for this rail type.
Definition road.h:95
SpriteID build_y_road
button for building single rail in Y direction
Definition road.h:77
struct RoadTypeInfo::@27 strings
Strings associated with the rail type.
CursorID tunnel
Cursor for building a tunnel.
Definition road.h:89
SpriteID auto_road
button for the autoroad construction
Definition road.h:78
SpriteID convert_road
button for converting road types
Definition road.h:81
CursorID road_swne
Cursor for building rail in X direction.
Definition road.h:85
StringID err_convert_road
Converting a road type.
Definition road.h:106
StringID err_depot
Building a depot.
Definition road.h:103
SpriteID build_x_road
button for building single rail in X direction
Definition road.h:76
SpriteID build_depot
button for building depots
Definition road.h:79
SpriteID build_tunnel
button for building a tunnel
Definition road.h:80
StringID err_build_station[2]
Building a bus or truck station.
Definition road.h:104
StringID err_remove_station[2]
Removing of a bus or truck station.
Definition road.h:105
struct RoadTypeInfo::@25 gui_sprites
struct containing the sprites for the road GUI.
StringID GetTypeTooltip() const override
Get the tooltip string for the type grid.
int GetSelectedType() const override
Get the selected type.
std::span< const BadgeID > GetTypeBadges(int cls_id, int id) const override
Get the item of a type.
StringID GetClassTooltip() const override
Get the tooltip string for the class list.
void DrawType(int x, int y, int cls_id, int id) const override
Draw preview image of an item.
bool IsActive() const override
Should picker class/type selection be enabled?
bool IsTypeAvailable(int cls_id, int id) const override
Test if an item is currently buildable.
void SetSelectedType(int id) const override
Set the selected type.
void FillUsedItems(std::set< PickerItem > &items) override
Fill a set with all items that are used by the current player.
StringID GetTypeName(int cls_id, int id) const override
Get the item of a type.
StringID GetClassName(int id) const override
Get the name of a class.
void SetSelectedClass(int id) const override
Set the selected class.
int GetSelectedClass() const override
Get the index of the selected class.
bool HasClassChoice() const override
Are there multiple classes to chose from?
static Date date
Current date in days (day counter).
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:29
int vsep_normal
Normal vertical spacing.
Definition window_gui.h:58
RectPadding fullbevel
Always-scaled bevel thickness.
Definition window_gui.h:39
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition window_gui.h:94
Functions related to commands.
static constexpr DoCommandFlags CommandFlagsToDCFlags(CommandFlags cmd_flags)
Extracts the DC flags needed for DoCommand from the flags returned by GetCommandFlags.
@ Auto
don't allow building on structures
Commands
List of commands.
Definition of stuff that is very close to a company, like the company struct itself.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Functions related to companies.
bool IsValidAxis(Axis d)
Checks if an integer value is a valid Axis.
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
Axis
Allow incrementing of DiagDirDiff variables.
@ INVALID_AXIS
Flag for an invalid Axis.
@ AXIS_X
The X axis.
@ AXIS_Y
The y axis.
DiagDirection
Enumeration for diagonal directions.
@ DIAGDIR_NE
Northeast, upper right on your monitor.
@ DIAGDIR_NW
Northwest.
@ DIAGDIR_END
Used for iterations.
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.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23)
Definition enum_type.hpp:17
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 GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition gfx.cpp:923
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:38
bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int height)
Set up a clipping area for only drawing into a certain area.
Definition gfx.cpp:1519
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:243
constexpr NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
Obtain a nested widget (sub)tree from an external source.
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 SetPIP(uint8_t pre, uint8_t inter, uint8_t post)
Widget part function for setting a pre/inter/post spaces.
constexpr NWidgetPart SetPadding(uint8_t top, uint8_t right, uint8_t bottom, uint8_t left)
Widget part function for setting additional space around a widget.
constexpr NWidgetPart SetStringTip(StringID string, StringID tip={})
Widget part function for setting the string and tooltip.
constexpr NWidgetPart SetTextStyle(TextColour colour, FontSize size=FS_NORMAL)
Widget part function for setting the text style.
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.
constexpr NWidgetPart SetPIPRatio(uint8_t ratio_pre, uint8_t ratio_inter, uint8_t ratio_post)
Widget part function for setting a pre/inter/post ratio.
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition window.cpp:943
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
GUI functions that shouldn't be here.
Hotkey related functions.
bool HandlePlacePushButton(Window *w, WidgetID widget, CursorID cursor, HighLightStyle mode)
This code is shared for the majority of the pushbuttons.
Definition main_gui.cpp:63
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:569
static debug_inline TileIndex TileVirtXY(uint x, uint y)
Get a tile from the virtual XY-coordinate.
Definition map_func.h:403
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
GrfSpecFeature
Definition newgrf.h:68
int DrawBadgeNameList(Rect r, std::span< const BadgeID > badges, GrfSpecFeature)
Draw names for a list of badge labels.
Functions related to NewGRF badges.
@ CBID_STATION_AVAILABILITY
Determine whether a newstation should be made available to build.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
@ Avail
Availability of road stop in construction window.
bool Convert8bitBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
NewGRF definitions and structures for road stops.
bool IsWaypointClass(const RoadStopClass &cls)
Test if a RoadStopClass is the waypoint class.
RoadStopClassID
@ ROADSTOP_CLASS_DFLT
Default road stop class.
@ ROADSTOP_CLASS_WAYP
Waypoint class.
@ ROADSTOPTYPE_FREIGHT
This RoadStop is for freight (truck) stops.
@ ROADSTOPTYPE_ALL
This RoadStop is for both types of station road stops.
@ ROADSTOPTYPE_PASSENGER
This RoadStop is for passenger (bus) stops.
@ RSV_DRIVE_THROUGH_X
Drive through road stop, X axis.
@ NoAutoRoadConnection
No auto road connection.
@ RoadOnly
Only show in the road build menu (not tram).
@ TramOnly
Only show in the tram build menu (not road).
@ DriveThroughOnly
Stop is drive-through only.
std::unique_ptr< NWidgetBase > MakePickerClassWidgets()
Create nested widgets for the class picker widgets.
std::unique_ptr< NWidgetBase > MakePickerTypeWidgets()
Create nested widgets for the type picker widgets.
Functions/types etc.
@ INVALID_RAILTYPE
Flag for invalid railtype.
Definition rail_type.h:34
RoadTypes GetCompanyRoadTypes(CompanyID company, bool introduces)
Get the road types the given company can build.
Definition road.cpp:199
RoadTypes GetRoadTypes(bool introduces)
Get list of road types, regardless of company availability.
Definition road.cpp:227
bool ValParamRoadType(RoadType roadtype)
Validate functions for rail building.
Definition road.cpp:153
RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, TimerGameCalendar::Date date)
Add the road types that are to be introduced at the given date.
Definition road.cpp:166
RoadTypes _roadtypes_type
Bitmap of road/tram types.
Definition road_cmd.cpp:62
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:220
void DrawRoadDepotSprite(int x, int y, DiagDirection dir, RoadType rt)
Draw the road depot sprite.
Road related functions.
RoadBits DiagDirToRoadBits(DiagDirection d)
Create the road-part which belongs to the given DiagDirection.
Definition road_func.h:96
static constexpr NWidgetPart _nested_road_station_picker_widgets[]
Widget definition of the build road station window.
void InitializeRoadGUI()
I really don't know why rail_gui.cpp has this too, shouldn't be included in the other one?
static constexpr NWidgetPart _nested_build_road_waypoint_widgets[]
Nested widget definition for the build NewGRF road waypoint window.
Window * ShowBuildRoadScenToolbar(RoadType roadtype)
Show the road building toolbar in the scenario editor.
void CcRoadStop(Commands, const CommandCost &result, TileIndex tile, uint8_t width, uint8_t length, RoadStopType, bool is_drive_through, DiagDirection dir, RoadType, RoadStopClassID spec_class, uint16_t spec_index, StationID, bool)
Command callback for building road stops.
Definition road_gui.cpp:195
static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, RoadStopType stop_type, bool adjacent, RoadType rt, StringID err_msg)
Place a new road stop.
Definition road_gui.cpp:229
static constexpr NWidgetPart _nested_tram_station_picker_widgets[]
Widget definition of the build tram station window.
static void PlaceRoad_TruckStation(TileIndex tile)
Callback for placing a truck station.
Definition road_gui.cpp:296
static bool IsRoadStopAvailable(const RoadStopSpec *spec, StationType type)
Check whether a road stop type can be built.
Definition road_gui.cpp:102
static void PlaceRoad_Bridge(TileIndex tile, Window *w)
Callback to start placing a bridge.
Definition road_gui.cpp:124
static void PlaceRoad_BusStation(TileIndex tile)
Callback for placing a bus station.
Definition road_gui.cpp:278
static void PlaceRoad_Waypoint(TileIndex tile)
Place a road waypoint.
Definition road_gui.cpp:255
static void ToggleRoadButton_Remove(Window *w)
Toggles state of the Remove button of Build road toolbar.
Definition road_gui.cpp:316
static RoadWaypointPickerSelection _waypoint_gui
Settings of the road waypoint picker.
Definition road_gui.cpp:74
static bool RoadToolbar_CtrlChanged(Window *w)
Updates the Remove button because of Ctrl state change.
Definition road_gui.cpp:329
Window * ShowBuildRoadToolbar(RoadType roadtype)
Open the build road toolbar window.
Definition road_gui.cpp:997
void ConnectRoadToStructure(TileIndex tile, DiagDirection direction)
If required, connects a new structure to an existing road or tram by building the missing roadbit.
Definition road_gui.cpp:163
Functions/types related to the road GUIs.
static debug_inline bool IsNormalRoadTile(Tile t)
Return whether a tile is a normal road tile.
Definition road_map.h:74
RoadBits GetRoadBits(Tile t, RoadTramType rtt)
Get the present road bits for a specific road type.
Definition road_map.h:128
@ ROAD_NONE
No road-part is build.
Definition road_type.h:53
RoadTypes
The different roadtypes we support, but then a bitmask of them.
Definition road_type.h:38
@ ROADTYPES_NONE
No roadtypes.
Definition road_type.h:39
RoadType
The different roadtypes we support.
Definition road_type.h:25
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:30
@ DRD_NORTHBOUND
All northbound traffic is disallowed.
Definition road_type.h:76
@ DRD_NONE
None of the directions are disallowed.
Definition road_type.h:74
Types related to the road widgets.
@ WID_BROS_LT_ON
Turn on area highlight.
Definition road_widget.h:55
@ WID_BROS_ACCEPTANCE
Station acceptance info.
Definition road_widget.h:56
@ WID_BROS_STATION_SW
Terminal station with SW entry.
Definition road_widget.h:50
@ WID_BROS_STATION_X
Drive-through station in x-direction.
Definition road_widget.h:52
@ WID_BROS_STATION_NE
Terminal station with NE entry.
Definition road_widget.h:48
@ WID_BROS_STATION_SE
Terminal station with SE entry.
Definition road_widget.h:49
@ WID_BROS_CAPTION
Caption of the window.
Definition road_widget.h:47
@ WID_BROS_AVAILABLE_ORIENTATIONS
Selection for selecting 6 or 2 orientations.
Definition road_widget.h:57
@ WID_BROS_STATION_NW
Terminal station with NW entry.
Definition road_widget.h:51
@ WID_BROS_STATION_Y
Drive-through station in y-direction.
Definition road_widget.h:53
@ WID_BROS_LT_OFF
Turn off area highlight.
Definition road_widget.h:54
RoadToolbarWidgets
Widgets of the BuildRoadToolbarWindow class.
Definition road_widget.h:14
@ WID_ROT_BUILD_BRIDGE
Build bridge.
Definition road_widget.h:26
@ WID_ROT_BUS_STATION
Build bus station.
Definition road_widget.h:23
@ WID_ROT_DEPOT
Build depot.
Definition road_widget.h:21
@ WID_ROT_CAPTION
Caption of the window.
Definition road_widget.h:16
@ WID_ROT_BUILD_WAYPOINT
Build waypoint.
Definition road_widget.h:22
@ WID_ROT_ROAD_Y
Build road in y-direction.
Definition road_widget.h:18
@ WID_ROT_AUTOROAD
Autorail.
Definition road_widget.h:19
@ WID_ROT_DEMOLISH
Demolish.
Definition road_widget.h:20
@ WID_ROT_BUILD_TUNNEL
Build tunnel.
Definition road_widget.h:27
@ WID_ROT_TRUCK_STATION
Build truck station.
Definition road_widget.h:24
@ WID_ROT_CONVERT_ROAD
Convert road.
Definition road_widget.h:29
@ WID_ROT_REMOVE
Remove road.
Definition road_widget.h:28
@ WID_ROT_ONE_WAY
Build one-way road.
Definition road_widget.h:25
@ WID_ROT_ROAD_X
Build road in x-direction.
Definition road_widget.h:17
@ WID_BROD_DEPOT_SE
Depot with SE entry.
Definition road_widget.h:39
@ WID_BROD_DEPOT_NE
Depot with NE entry.
Definition road_widget.h:38
@ WID_BROD_CAPTION
Caption of the window.
Definition road_widget.h:37
@ WID_BROD_DEPOT_NW
Depot with NW entry.
Definition road_widget.h:41
@ WID_BROD_DEPOT_SW
Depot with SW entry.
Definition road_widget.h:40
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:58
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:57
Functions related to sound.
@ SND_15_BEEP
19 == 0x13 GUI button click
Definition sound_type.h:66
@ SND_1F_CONSTRUCTION_OTHER
29 == 0x1D Construction: other (non-water, non-rail, non-bridge)
Definition sound_type.h:76
static const CursorID ANIMCURSOR_DEMOLISH
704 - 707 - demolish dynamite
Definition sprites.h:1512
Base classes/functions for stations.
Command definitions related to stations.
Functions related to stations.
void ShowSelectStationIfNeeded(TileArea ta, StationPickerCmdProc proc)
Show the station selection window when needed.
int DrawStationCoverageAreaText(const Rect &r, StationCoverageType sct, int rad, bool supplies)
Calculates and draws the accepted or supplied cargo around the selected tile(s)
void CheckRedrawStationCoverage(const Window *w)
Check whether we need to redraw the station coverage text.
void ShowSelectRoadWaypointIfNeeded(TileArea ta, StationPickerCmdProc proc)
Show the road waypoint selection window when needed.
Contains enums and function declarations connected with stations GUI.
StationCoverageType
Types of cargo to display for station coverage.
Definition station_gui.h:21
@ SCT_NON_PASSENGERS_ONLY
Draw all non-passenger class cargoes.
Definition station_gui.h:23
@ SCT_PASSENGERS_ONLY
Draw only passenger class cargoes.
Definition station_gui.h:22
RoadStopType
Types of RoadStops.
@ Bus
A standard stop for buses.
@ Truck
A standard stop for trucks.
@ TruckStop
Station with truck stops.
@ BusStop
Station with bus stops.
StationType
Station types.
static constexpr uint CA_BUS
Catchment for bus stops with "modified catchment" enabled.
static constexpr uint CA_UNMODIFIED
Catchment for all stations with "modified catchment" disabled.
static constexpr uint CA_TRUCK
Catchment for truck stops with "modified catchment" enabled.
Definition of base types and functions in a cross-platform compatible way.
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:426
Functions related to OTTD's strings.
int64_t PackVelocity(uint speed, VehicleType type)
Pack velocity and vehicle type for use with SCC_VELOCITY string parameter.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
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.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
uint coverage_height
Height of the coverage texts.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
StationType GetRoadStationTypeByWindowClass(WindowClass window_class) const
Simply to have a easier way to get the StationType for bus, truck and trams from the WindowClass.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
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.
void OnPaint() override
The window must be repainted.
void OnRealtimeTick(uint delta_ms) override
Called periodically.
Road toolbar window handler.
Definition road_gui.cpp:345
void OnPlaceObjectAbort() override
The user cancelled a tile highlight mode that has been set.
Definition road_gui.cpp:667
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
Definition road_gui.cpp:441
void ModifyRoadType(RoadType roadtype)
Switch to another road type.
Definition road_gui.cpp:435
void OnRealtimeTick(uint delta_ms) override
Called periodically.
Definition road_gui.cpp:826
void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) override
The user is dragging over the map when the tile highlight mode has been set.
Definition road_gui.cpp:688
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
Definition road_gui.cpp:364
static EventState RoadTramToolbarGlobalHotkeys(int hotkey, RoadType last_build, RoadTramType rtt)
Handler for global hotkeys of the BuildRoadToolbarWindow.
Definition road_gui.cpp:837
void OnPlaceObject(Point pt, TileIndex tile) override
The user clicked some place on the map when a tile highlight mode has been set.
Definition road_gui.cpp:605
EventState OnHotkey(int hotkey) override
A hotkey has been pressed.
Definition road_gui.cpp:599
void OnPlacePresize(Point pt, TileIndex tile) override
The user moves over the map when a tile highlight mode has been set when the special mouse mode has b...
Definition road_gui.cpp:814
void OnInit() override
Notification that the nested widget tree gets initialized.
Definition road_gui.cpp:417
int last_started_action
Last started user action.
Definition road_gui.cpp:347
RoadType roadtype
Road type to build.
Definition road_gui.cpp:346
void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override
The user has dragged over the map when the tile highlight mode has been set.
Definition road_gui.cpp:727
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition road_gui.cpp:510
void UpdateOptionWidgetStatus(RoadToolbarWidgets clicked_widget)
Update the remove button lowered state of the road toolbar.
Definition road_gui.cpp:460
EventState OnCTRLStateChange() override
The state of the control key has changed.
Definition road_gui.cpp:820
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition road_gui.cpp:376
SoundSettings sound
sound effect settings
GUISettings gui
settings related to the GUI
RoadTypes avail_roadtypes
Road types available to this company.
Dimensions (a width and height) of a rectangle in 2D.
Data about how and where to blit pixels.
Definition gfx_type.h:156
const struct GRFFile * grffile
grf file that introduced this entity
bool persistent_buildingtools
keep the building tools active after usage
bool station_show_coverage
whether to highlight coverage area
bool link_terraform_toolbar
display terraform toolbar when displaying rail, road, water and airport toolbars
StationSettings station
settings related to station management
List of hotkeys for a window.
Definition hotkeys.h:37
All data for a single hotkey.
Definition hotkeys.h:21
Partial widget specification to allow NWidgets to be written nested.
Represents the covered area of e.g.
uint16_t w
The width of the area.
TileIndex tile
The base tile of the area.
uint16_t h
The height of the area.
Coordinates of a point in 2D.
static Titem * Get(auto index)
Returns Titem with given index.
Tindex index
Index of this pool item.
static bool IsValidID(auto index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
constexpr uint Horizontal() const
Get total horizontal padding of RectPadding.
constexpr uint Vertical() const
Get total vertical padding of RectPadding.
Specification of a rectangle with absolute coordinates of all edges.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
RoadStopClassID sel_class
Selected road stop class.
Definition road_gui.cpp:77
DiagDirection orientation
Selected orientation of the road stop.
Definition road_gui.cpp:79
uint16_t sel_type
Selected road stop type within the class.
Definition road_gui.cpp:78
Road stop specification.
VariableGRFFileProps grf_prop
Properties related the the grf file.
RoadStopClassID sel_class
Selected road waypoint class.
Definition road_gui.cpp:71
uint16_t sel_type
Selected road waypoint type within the class.
Definition road_gui.cpp:72
bool click_beep
Beep on a random selection of buttons.
bool confirm
Play sound effect on successful constructions or other actions.
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
uint8_t station_spread
amount a station may spread
bool modified_catchment
different-size catchment areas
Station data structure.
Point size
Size, in tile "units", of the white/red selection area.
Point pos
Location, in tile "units", of the northern tile of the selected area.
Representation of a waypoint.
High level window description.
Definition window_gui.h:168
Number to differentiate different windows of the same class.
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
virtual void Close(int data=0)
Hide the window and all its child windows, and mark them for a later deletion.
Definition window.cpp:1050
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
void RaiseWidget(WidgetID widget_index)
Marks a widget as raised.
Definition window_gui.h:470
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:554
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
Definition window.cpp:502
ResizeInfo resize
Resize information.
Definition window_gui.h:315
void DisableWidget(WidgetID widget_index)
Sets a widget to disabled.
Definition window_gui.h:392
void SetWidgetsDisabledState(bool disab_stat, Args... widgets)
Sets the enabled/disabled status of a list of widgets.
Definition window_gui.h:516
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1726
WindowClass window_class
Window class.
Definition window_gui.h:302
bool IsWidgetLowered(WidgetID widget_index) const
Gets the lowered state of a widget.
Definition window_gui.h:492
bool IsWidgetDisabled(WidgetID widget_index) const
Gets the enabled/disabled status of a widget.
Definition window_gui.h:411
void RaiseButtons(bool autoraise=false)
Raise the buttons of the window.
Definition window.cpp:528
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
virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
The user has dragged over the map when the tile highlight mode has been set.
Definition window_gui.h:833
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:973
void LowerWidget(WidgetID widget_index)
Marks a widget as lowered.
Definition window_gui.h:461
virtual EventState OnHotkey(int hotkey)
A hotkey has been pressed.
Definition window.cpp:568
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:382
void ToggleWidgetLoweredState(WidgetID widget_index)
Invert the lowered/raised status of a widget.
Definition window_gui.h:451
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:303
bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_tile, TileIndex end_tile)
A central place to handle all X_AND_Y dragged GUI functions.
void PlaceProc_DemolishArea(TileIndex tile)
Start a drag for demolishing an area.
Window * ShowTerraformToolbar(Window *link)
Show the toolbar for terraforming in the game.
GUI stuff related to terraforming.
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95
Functions related to tile highlights.
void ResetObjectToPlace()
Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows).
void VpSetPresizeRange(TileIndex from, TileIndex to)
Highlights all tiles between a set of two tiles.
void VpSelectTilesWithMethod(int x, int y, ViewportPlaceMethod method)
Selects tiles while dragging.
void VpStartPlaceSizing(TileIndex tile, ViewportPlaceMethod method, ViewportDragDropSelectionProcess process)
highlighting tiles while only going over them with the mouse
@ HT_DIAGONAL
Also allow 'diagonal rectangles'. Only usable in combination with HT_RECT or HT_POINT.
@ HT_RECT
rectangle (stations, depots, ...)
@ HT_SPECIAL
special mode used for highlighting while dragging (and for tunnels/docks)
Definition of Interval and OneShot timers.
Definition of the game-calendar-timer.
@ TRANSPORT_ROAD
Transport by road vehicle.
Header file for things common for tunnels and bridges.
TileIndex _build_tunnel_endtile
The end of a tunnel; as hidden return from the tunnel build command for GUI purposes.
Command definitions related to tunnels and bridges.
Functions that have tunnels and bridges in common.
DiagDirection GetTunnelBridgeDirection(Tile t)
Get the direction pointing to the other end.
TileIndex GetOtherTunnelBridgeEnd(Tile t)
Determines type of the wormhole and returns its other end.
bool CanBuildVehicleInfrastructure(VehicleType type, uint8_t subtype)
Check whether we can build infrastructure for the given vehicle type.
Definition vehicle.cpp:1913
Functions related to vehicles.
@ VEH_ROAD
Road vehicle type.
void SetTileSelectSize(int w, int h)
Highlight w by h tiles at the cursor.
void SetRedErrorSquare(TileIndex tile)
Set a tile to display a red error square.
void SetViewportCatchmentStation(const Station *st, bool sel)
Select or deselect station for coverage area highlight.
Functions related to (drawing on) viewports.
ViewportPlaceMethod
Viewport place method (type of highlighted area and placed objects)
@ VPM_FIX_Y
drag only in Y axis
@ VPM_Y_LIMITED
Drag only in Y axis with limited size.
@ VPM_X_AND_Y_LIMITED
area of land of limited size
@ VPM_X_LIMITED
Drag only in X axis with limited size.
@ VPM_X_AND_Y
area of land in X and Y directions
@ VPM_FIX_X
drag only in X axis
@ VPM_X_OR_Y
drag in X or Y direction
ViewportDragDropSelectionProcess
Drag and drop selection process, or, what to do with an area of land when you've selected it.
@ DDSP_PLACE_ROAD_Y_DIR
Road placement (Y axis)
@ DDSP_BUILD_BUSSTOP
Road stop placement (buses)
@ DDSP_REMOVE_BUSSTOP
Road stop removal (buses)
@ DDSP_REMOVE_ROAD_WAYPOINT
Road stop removal (waypoint)
@ DDSP_DEMOLISH_AREA
Clear area.
@ DDSP_BUILD_TRUCKSTOP
Road stop placement (trucks)
@ DDSP_REMOVE_TRUCKSTOP
Road stop removal (trucks)
@ DDSP_PLACE_AUTOROAD
Road placement (auto)
@ DDSP_BUILD_ROAD_WAYPOINT
Road stop placement (waypoint)
@ DDSP_PLACE_ROAD_X_DIR
Road placement (X axis)
@ DDSP_BUILD_BRIDGE
Bridge placement.
@ DDSP_CONVERT_ROAD
Road conversion.
Base of waypoints.
@ WPF_ROAD
This is a road waypoint.
Axis GetAxisForNewRoadWaypoint(TileIndex tile)
Get the axis for a new road waypoint.
Command definitions related to waypoints.
Functions related to waypoints.
static RectPadding ScaleGUITrad(const RectPadding &r)
Scale a RectPadding to GUI zoom level.
Definition widget.cpp:48
@ WWT_IMGBTN
(Toggle) Button with image
Definition widget_type.h:42
@ 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_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_VERTICAL
Vertical container.
Definition widget_type.h:67
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:59
@ WWT_EMPTY
Empty widget, place holder to reserve space in widget tree.
Definition widget_type.h:38
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition widget_type.h:55
@ NWID_HORIZONTAL_LTR
Horizontal container that doesn't change the order of the widgets for RTL languages.
Definition widget_type.h:66
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:70
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 CloseWindowByClass(WindowClass cls, int data)
Close all windows of a given class.
Definition window.cpp:1155
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition window.cpp:1101
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.
@ WDP_AUTO
Find a place automatically.
Definition window_gui.h:145
@ WDP_ALIGN_TOOLBAR
Align toward the toolbar.
Definition window_gui.h:147
int WidgetID
Widget ID.
Definition window_type.h:20
EventState
State of handling an event.
@ ES_HANDLED
The passed event is handled.
@ ES_NOT_HANDLED
The passed event is not handled.
WindowClass
Window classes.
Definition window_type.h:46
@ WC_SCEN_BUILD_TOOLBAR
Scenario build toolbar; Window numbers:
Definition window_type.h:82
@ WC_BUILD_TOOLBAR
Build toolbar; Window numbers:
Definition window_type.h:75
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:47
@ WC_SCEN_LAND_GEN
Landscape generation (in Scenario Editor); Window numbers:
@ WC_SELECT_STATION
Select station (when joining stations); Window numbers:
@ WC_BUILD_DEPOT
Build depot; Window numbers:
@ WC_TRUCK_STATION
Build truck station; Window numbers:
@ WC_BUS_STATION
Build bus station; Window numbers:
@ WC_BUILD_WAYPOINT
Build waypoint; Window numbers:
@ WC_BUILD_BRIDGE
Build bridge; Window numbers:
Functions related to zooming.
int ScaleSpriteTrad(int value)
Scale traditional pixel dimensions to GUI zoom level, for drawing sprites.
Definition zoom_func.h:107