OpenTTD Source 20241224-master-gf74b0cf984
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_roadstop.h"
43#include "picker_gui.h"
44#include "timer/timer.h"
46
47#include "widgets/road_widget.h"
48
49#include "table/strings.h"
50
51#include "safeguards.h"
52
53static void ShowRVStationPicker(Window *parent, RoadStopType rs);
54static void ShowRoadDepotPicker(Window *parent);
55static void ShowBuildRoadWaypointPicker(Window *parent);
56
57static bool _remove_button_clicked;
58static bool _one_way_button_clicked;
59
60static Axis _place_road_dir;
61static bool _place_road_start_half_x;
62static bool _place_road_start_half_y;
63static bool _place_road_end_half;
64
65static RoadType _cur_roadtype;
66
67static DiagDirection _road_depot_orientation;
68
74
80static RoadStopPickerSelection _roadstop_gui;
81
82static bool IsRoadStopEverAvailable(const RoadStopSpec *spec, StationType type)
83{
84 if (spec == nullptr) return true;
85
86 if (HasBit(spec->flags, RSF_BUILD_MENU_ROAD_ONLY) && !RoadTypeIsRoad(_cur_roadtype)) return false;
87 if (HasBit(spec->flags, RSF_BUILD_MENU_TRAM_ONLY) && !RoadTypeIsTram(_cur_roadtype)) return false;
88
89 switch (spec->stop_type) {
90 case ROADSTOPTYPE_ALL: return true;
91 case ROADSTOPTYPE_PASSENGER: return type == STATION_BUS;
92 case ROADSTOPTYPE_FREIGHT: return type == STATION_TRUCK;
93 default: NOT_REACHED();
94 }
95}
96
101static bool IsRoadStopAvailable(const RoadStopSpec *spec, StationType type)
102{
103 if (spec == nullptr) return true;
104 if (!IsRoadStopEverAvailable(spec, type)) return false;
105
106 if (!HasBit(spec->callback_mask, CBM_ROAD_STOP_AVAIL)) return true;
107
108 uint16_t cb_res = GetRoadStopCallback(CBID_STATION_AVAILABILITY, 0, 0, spec, nullptr, INVALID_TILE, _cur_roadtype, type, 0);
109 if (cb_res == CALLBACK_FAILED) return true;
110
112}
113
114void CcPlaySound_CONSTRUCTION_OTHER(Commands, const CommandCost &result, TileIndex tile)
115{
116 if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile);
117}
118
123static void PlaceRoad_Bridge(TileIndex tile, Window *w)
124{
125 if (IsBridgeTile(tile)) {
126 TileIndex other_tile = GetOtherTunnelBridgeEnd(tile);
127 Point pt = {0, 0};
128 w->OnPlaceMouseUp(VPM_X_OR_Y, DDSP_BUILD_BRIDGE, pt, other_tile, tile);
129 } else {
131 }
132}
133
140void CcBuildRoadTunnel(Commands, const CommandCost &result, TileIndex start_tile)
141{
142 if (result.Succeeded()) {
143 if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, start_tile);
145
146 DiagDirection start_direction = ReverseDiagDir(GetTunnelBridgeDirection(start_tile));
147 ConnectRoadToStructure(start_tile, start_direction);
148
149 TileIndex end_tile = GetOtherTunnelBridgeEnd(start_tile);
150 DiagDirection end_direction = ReverseDiagDir(GetTunnelBridgeDirection(end_tile));
151 ConnectRoadToStructure(end_tile, end_direction);
152 } else {
154 }
155}
156
163{
164 tile += TileOffsByDiagDir(direction);
165 /* if there is a roadpiece just outside of the station entrance, build a connecting route */
166 if (IsNormalRoadTile(tile)) {
167 if (GetRoadBits(tile, GetRoadTramType(_cur_roadtype)) != ROAD_NONE) {
168 Command<CMD_BUILD_ROAD>::Post(tile, DiagDirToRoadBits(ReverseDiagDir(direction)), _cur_roadtype, DRD_NONE, 0);
169 }
170 }
171}
172
173void CcRoadDepot(Commands, const CommandCost &result, TileIndex tile, RoadType, DiagDirection dir)
174{
175 if (result.Failed()) return;
176
179 ConnectRoadToStructure(tile, dir);
180}
181
194void CcRoadStop(Commands, const CommandCost &result, TileIndex tile, uint8_t width, uint8_t length, RoadStopType, bool is_drive_through,
195 DiagDirection dir, RoadType, RoadStopClassID spec_class, uint16_t spec_index, StationID, bool)
196{
197 if (result.Failed()) return;
198
201
202 bool connect_to_road = true;
203 if ((uint)spec_class < RoadStopClass::GetClassCount() && spec_index < RoadStopClass::Get(spec_class)->GetSpecCount()) {
204 const RoadStopSpec *roadstopspec = RoadStopClass::Get(spec_class)->GetSpec(spec_index);
205 if (roadstopspec != nullptr && HasBit(roadstopspec->flags, RSF_NO_AUTO_ROAD_CONNECTION)) connect_to_road = false;
206 }
207
208 if (connect_to_road) {
209 TileArea roadstop_area(tile, width, length);
210 for (TileIndex cur_tile : roadstop_area) {
211 ConnectRoadToStructure(cur_tile, dir);
212 /* For a drive-through road stop build connecting road for other entrance. */
213 if (is_drive_through) ConnectRoadToStructure(cur_tile, ReverseDiagDir(dir));
214 }
215 }
216}
217
228static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, RoadStopType stop_type, bool adjacent, RoadType rt, StringID err_msg)
229{
230 TileArea ta(start_tile, end_tile);
231 DiagDirection ddir = _roadstop_gui.orientation;
232 bool drive_through = ddir >= DIAGDIR_END;
233 if (drive_through) ddir = static_cast<DiagDirection>(ddir - DIAGDIR_END); // Adjust picker result to actual direction.
234 RoadStopClassID spec_class = _roadstop_gui.sel_class;
235 uint16_t spec_index = _roadstop_gui.sel_type;
236
237 auto proc = [=](bool test, StationID to_join) -> bool {
238 if (test) {
239 return Command<CMD_BUILD_ROAD_STOP>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_ROAD_STOP>()), ta.tile, ta.w, ta.h, stop_type, drive_through,
240 ddir, rt, spec_class, spec_index, INVALID_STATION, adjacent).Succeeded();
241 } else {
242 return Command<CMD_BUILD_ROAD_STOP>::Post(err_msg, CcRoadStop, ta.tile, ta.w, ta.h, stop_type, drive_through,
243 ddir, rt, spec_class, spec_index, to_join, adjacent);
244 }
245 };
246
248}
249
255{
256 if (_remove_button_clicked) {
258 return;
259 }
260
261 Axis axis = GetAxisForNewRoadWaypoint(tile);
262 if (IsValidAxis(axis)) {
263 /* Valid tile for waypoints */
265 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
266 } else {
267 /* Tile where we can't build road waypoints. This is always going to fail,
268 * but provides the user with a proper error message. */
269 Command<CMD_BUILD_ROAD_WAYPOINT>::Post(STR_ERROR_CAN_T_BUILD_ROAD_WAYPOINT, tile, AXIS_X, 1, 1, ROADSTOP_CLASS_WAYP, 0, INVALID_STATION, false);
270 }
271}
272
278{
279 if (_remove_button_clicked) {
281 } else {
282 if (_roadstop_gui.orientation < DIAGDIR_END) { // Not a drive-through stop.
284 } else {
286 }
287 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
288 }
289}
290
296{
297 if (_remove_button_clicked) {
299 } else {
300 if (_roadstop_gui.orientation < DIAGDIR_END) { // Not a drive-through stop.
302 } else {
304 }
305 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
306 }
307}
308
309typedef void OnButtonClick(Window *w);
310
316{
319 _remove_button_clicked = w->IsWidgetLowered(WID_ROT_REMOVE);
320 SetSelectionRed(_remove_button_clicked);
321}
322
329{
330 if (w->IsWidgetDisabled(WID_ROT_REMOVE)) return false;
331
332 /* allow ctrl to switch remove mode only for these widgets */
333 for (WidgetID i = WID_ROT_ROAD_X; i <= WID_ROT_AUTOROAD; i++) {
334 if (w->IsWidgetLowered(i)) {
336 return true;
337 }
338 }
339
340 return false;
341}
342
347
349 {
350 this->roadtype = _cur_roadtype;
351 this->CreateNestedTree();
352 this->FinishInitNested(window_number);
354
355 if (RoadTypeIsRoad(this->roadtype)) {
357 }
358
359 this->OnInvalidateData();
360 this->last_started_action = INVALID_WID_ROT;
361
363 }
364
365 void Close([[maybe_unused]] int data = 0) override
366 {
367 if (_game_mode == GM_NORMAL && (this->IsWidgetLowered(WID_ROT_BUS_STATION) || this->IsWidgetLowered(WID_ROT_TRUCK_STATION))) SetViewportCatchmentStation(nullptr, true);
369 this->Window::Close();
370 }
371
377 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
378 {
379 if (!gui_scope) return;
380
381 if (!ValParamRoadType(this->roadtype)) {
382 /* Close toolbar if road type is not available. */
383 this->Close();
384 return;
385 }
386
387 RoadTramType rtt = GetRoadTramType(this->roadtype);
388
390 this->SetWidgetsDisabledState(!can_build,
395 if (!can_build) {
400 }
401
402 if (_game_mode != GM_EDITOR) {
403 if (!can_build) {
404 /* Show in the tooltip why this button is disabled. */
409 } else {
414 }
415 }
416 }
417
418 void OnInit() override
419 {
420 /* Configure the road toolbar for the roadtype. */
421 const RoadTypeInfo *rti = GetRoadTypeInfo(this->roadtype);
425 if (_game_mode != GM_EDITOR) {
427 }
430 }
431
437 {
438 this->roadtype = roadtype;
439 this->ReInit();
440 }
441
442 void SetStringParameters(WidgetID widget) const override
443 {
444 if (widget == WID_ROT_CAPTION) {
445 const RoadTypeInfo *rti = GetRoadTypeInfo(this->roadtype);
446 if (rti->max_speed > 0) {
450 } else {
452 }
453 }
454 }
455
462 {
463 /* The remove and the one way button state is driven
464 * by the other buttons so they don't act on themselves.
465 * Both are only valid if they are able to apply as options. */
466 switch (clicked_widget) {
467 case WID_ROT_REMOVE:
468 if (RoadTypeIsRoad(this->roadtype)) {
471 }
472
473 break;
474
475 case WID_ROT_ONE_WAY:
478 break;
479
483 if (RoadTypeIsRoad(this->roadtype)) this->DisableWidget(WID_ROT_ONE_WAY);
484 this->SetWidgetDisabledState(WID_ROT_REMOVE, !this->IsWidgetLowered(clicked_widget));
485 break;
486
487 case WID_ROT_ROAD_X:
488 case WID_ROT_ROAD_Y:
489 case WID_ROT_AUTOROAD:
490 this->SetWidgetDisabledState(WID_ROT_REMOVE, !this->IsWidgetLowered(clicked_widget));
491 if (RoadTypeIsRoad(this->roadtype)) {
492 this->SetWidgetDisabledState(WID_ROT_ONE_WAY, !this->IsWidgetLowered(clicked_widget));
493 }
494 break;
495
496 default:
497 /* When any other buttons than road/station, raise and
498 * disable the removal button */
501
502 if (RoadTypeIsRoad(this->roadtype)) {
505 }
506
507 break;
508 }
509 }
510
511 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
512 {
513 _remove_button_clicked = false;
514 _one_way_button_clicked = false;
515 switch (widget) {
516 case WID_ROT_ROAD_X:
518 this->last_started_action = widget;
519 break;
520
521 case WID_ROT_ROAD_Y:
523 this->last_started_action = widget;
524 break;
525
526 case WID_ROT_AUTOROAD:
528 this->last_started_action = widget;
529 break;
530
531 case WID_ROT_DEMOLISH:
533 this->last_started_action = widget;
534 break;
535
536 case WID_ROT_DEPOT:
537 if (HandlePlacePushButton(this, WID_ROT_DEPOT, GetRoadTypeInfo(this->roadtype)->cursor.depot, HT_RECT)) {
538 ShowRoadDepotPicker(this);
539 this->last_started_action = widget;
540 }
541 break;
542
544 this->last_started_action = widget;
545 if (HandlePlacePushButton(this, WID_ROT_BUILD_WAYPOINT, SPR_CURSOR_WAYPOINT, HT_RECT)) {
546 ShowBuildRoadWaypointPicker(this);
547 }
548 break;
549
551 if (HandlePlacePushButton(this, WID_ROT_BUS_STATION, SPR_CURSOR_BUS_STATION, HT_RECT)) {
552 ShowRVStationPicker(this, ROADSTOP_BUS);
553 this->last_started_action = widget;
554 }
555 break;
556
558 if (HandlePlacePushButton(this, WID_ROT_TRUCK_STATION, SPR_CURSOR_TRUCK_STATION, HT_RECT)) {
559 ShowRVStationPicker(this, ROADSTOP_TRUCK);
560 this->last_started_action = widget;
561 }
562 break;
563
564 case WID_ROT_ONE_WAY:
565 if (this->IsWidgetDisabled(WID_ROT_ONE_WAY)) return;
566 this->SetDirty();
568 SetSelectionRed(false);
569 break;
570
572 HandlePlacePushButton(this, WID_ROT_BUILD_BRIDGE, SPR_CURSOR_BRIDGE, HT_RECT);
573 this->last_started_action = widget;
574 break;
575
578 this->last_started_action = widget;
579 break;
580
581 case WID_ROT_REMOVE:
582 if (this->IsWidgetDisabled(WID_ROT_REMOVE)) return;
583
587 break;
588
591 this->last_started_action = widget;
592 break;
593
594 default: NOT_REACHED();
595 }
598 }
599
601 {
602 MarkTileDirtyByTile(TileVirtXY(_thd.pos.x, _thd.pos.y)); // redraw tile selection
603 return Window::OnHotkey(hotkey);
604 }
605
606 void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override
607 {
608 _remove_button_clicked = this->IsWidgetLowered(WID_ROT_REMOVE);
609 _one_way_button_clicked = RoadTypeIsRoad(this->roadtype) ? this->IsWidgetLowered(WID_ROT_ONE_WAY) : false;
610 switch (this->last_started_action) {
611 case WID_ROT_ROAD_X:
612 _place_road_dir = AXIS_X;
613 _place_road_start_half_x = _tile_fract_coords.x >= 8;
615 break;
616
617 case WID_ROT_ROAD_Y:
618 _place_road_dir = AXIS_Y;
619 _place_road_start_half_y = _tile_fract_coords.y >= 8;
621 break;
622
623 case WID_ROT_AUTOROAD:
624 _place_road_dir = INVALID_AXIS;
625 _place_road_start_half_x = _tile_fract_coords.x >= 8;
626 _place_road_start_half_y = _tile_fract_coords.y >= 8;
628 break;
629
630 case WID_ROT_DEMOLISH:
632 break;
633
634 case WID_ROT_DEPOT:
635 Command<CMD_BUILD_ROAD_DEPOT>::Post(GetRoadTypeInfo(this->roadtype)->strings.err_depot, CcRoadDepot,
636 tile, _cur_roadtype, _road_depot_orientation);
637 break;
638
640 PlaceRoad_Waypoint(tile);
641 break;
642
645 break;
646
649 break;
650
652 PlaceRoad_Bridge(tile, this);
653 break;
654
657 tile, TRANSPORT_ROAD, _cur_roadtype);
658 break;
659
662 break;
663
664 default: NOT_REACHED();
665 }
666 }
667
688
690 {
691 /* Here we update the end tile flags
692 * of the road placement actions.
693 * At first we reset the end halfroad
694 * bits and if needed we set them again. */
695 switch (select_proc) {
697 _place_road_end_half = pt.x & 8;
698 break;
699
701 _place_road_end_half = pt.y & 8;
702 break;
703
705 /* For autoroad we need to update the
706 * direction of the road */
707 if (_thd.size.x > _thd.size.y || (_thd.size.x == _thd.size.y &&
708 ( (_tile_fract_coords.x < _tile_fract_coords.y && (_tile_fract_coords.x + _tile_fract_coords.y) < 16) ||
709 (_tile_fract_coords.x > _tile_fract_coords.y && (_tile_fract_coords.x + _tile_fract_coords.y) > 16) ))) {
710 /* Set dir = X */
711 _place_road_dir = AXIS_X;
712 _place_road_end_half = pt.x & 8;
713 } else {
714 /* Set dir = Y */
715 _place_road_dir = AXIS_Y;
716 _place_road_end_half = pt.y & 8;
717 }
718
719 break;
720
721 default:
722 break;
723 }
724
725 VpSelectTilesWithMethod(pt.x, pt.y, select_method);
726 }
727
728 void OnPlaceMouseUp([[maybe_unused]] ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt, TileIndex start_tile, TileIndex end_tile) override
729 {
730 if (pt.x != -1) {
731 switch (select_proc) {
732 default: NOT_REACHED();
735 ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, _cur_roadtype);
736 break;
737
739 GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
740 break;
741
744 case DDSP_PLACE_AUTOROAD: {
745 bool start_half = _place_road_dir == AXIS_Y ? _place_road_start_half_y : _place_road_start_half_x;
746
747 if (_remove_button_clicked) {
748 Command<CMD_REMOVE_LONG_ROAD>::Post(GetRoadTypeInfo(this->roadtype)->strings.err_remove_road, CcPlaySound_CONSTRUCTION_OTHER,
749 end_tile, start_tile, _cur_roadtype, _place_road_dir, start_half, _place_road_end_half);
750 } else {
751 Command<CMD_BUILD_LONG_ROAD>::Post(GetRoadTypeInfo(this->roadtype)->strings.err_build_road, CcPlaySound_CONSTRUCTION_OTHER,
752 end_tile, start_tile, _cur_roadtype, _place_road_dir, _one_way_button_clicked ? DRD_NORTHBOUND : DRD_NONE, start_half, _place_road_end_half, false);
753 }
754 break;
755 }
756
760 if (_remove_button_clicked) {
761 Command<CMD_REMOVE_FROM_ROAD_WAYPOINT>::Post(STR_ERROR_CAN_T_REMOVE_ROAD_WAYPOINT, CcPlaySound_CONSTRUCTION_OTHER, end_tile, start_tile);
762 } else {
763 TileArea ta(start_tile, end_tile);
764 Axis axis = select_method == VPM_X_LIMITED ? AXIS_X : AXIS_Y;
765 bool adjacent = _ctrl_pressed;
766
767 auto proc = [=](bool test, StationID to_join) -> bool {
768 if (test) {
770 } else {
772 }
773 };
774
776 }
777 }
778 break;
779
782 if (this->IsWidgetLowered(WID_ROT_BUS_STATION) && GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui.sel_class), ROADSTOP_BUS, _cur_roadtype)) {
783 if (_remove_button_clicked) {
784 TileArea ta(start_tile, end_tile);
785 Command<CMD_REMOVE_ROAD_STOP>::Post(GetRoadTypeInfo(this->roadtype)->strings.err_remove_station[ROADSTOP_BUS], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w, ta.h, ROADSTOP_BUS, _ctrl_pressed);
786 } else {
787 PlaceRoadStop(start_tile, end_tile, ROADSTOP_BUS, _ctrl_pressed, _cur_roadtype, GetRoadTypeInfo(this->roadtype)->strings.err_build_station[ROADSTOP_BUS]);
788 }
789 }
790 break;
791
794 if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION) && GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui.sel_class), ROADSTOP_TRUCK, _cur_roadtype)) {
795 if (_remove_button_clicked) {
796 TileArea ta(start_tile, end_tile);
797 Command<CMD_REMOVE_ROAD_STOP>::Post(GetRoadTypeInfo(this->roadtype)->strings.err_remove_station[ROADSTOP_TRUCK], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w, ta.h, ROADSTOP_TRUCK, _ctrl_pressed);
798 } else {
799 PlaceRoadStop(start_tile, end_tile, ROADSTOP_TRUCK, _ctrl_pressed, _cur_roadtype, GetRoadTypeInfo(this->roadtype)->strings.err_build_station[ROADSTOP_TRUCK]);
800 }
801 }
802 break;
803
805 Command<CMD_CONVERT_ROAD>::Post(GetRoadTypeInfo(this->roadtype)->strings.err_convert_road, CcPlaySound_CONSTRUCTION_OTHER, end_tile, start_tile, _cur_roadtype);
806 break;
807 }
808 }
809 }
810
816
818 {
819 if (RoadToolbar_CtrlChanged(this)) return ES_HANDLED;
820 return ES_NOT_HANDLED;
821 }
822
823 void OnRealtimeTick([[maybe_unused]] uint delta_ms) override
824 {
825 if (_game_mode == GM_NORMAL && this->IsWidgetLowered(WID_ROT_BUILD_WAYPOINT)) CheckRedrawRoadWaypointCoverage(this);
826 }
827
835 {
836 Window *w = nullptr;
837 switch (_game_mode) {
838 case GM_NORMAL:
840 break;
841
842 case GM_EDITOR:
843 if ((GetRoadTypes(true) & ((rtt == RTT_ROAD) ? ~_roadtypes_type : _roadtypes_type)) == ROADTYPES_NONE) return ES_NOT_HANDLED;
845 break;
846
847 default:
848 break;
849 }
850
851 if (w == nullptr) return ES_NOT_HANDLED;
852 return w->OnHotkey(hotkey);
853 }
854
855 static EventState RoadToolbarGlobalHotkeys(int hotkey)
856 {
857 extern RoadType _last_built_roadtype;
858 return RoadTramToolbarGlobalHotkeys(hotkey, _last_built_roadtype, RTT_ROAD);
859 }
860
861 static EventState TramToolbarGlobalHotkeys(int hotkey)
862 {
863 extern RoadType _last_built_tramtype;
864 return RoadTramToolbarGlobalHotkeys(hotkey, _last_built_tramtype, RTT_TRAM);
865 }
866
867 static inline HotkeyList road_hotkeys{"roadtoolbar", {
868 Hotkey('1', "build_x", WID_ROT_ROAD_X),
869 Hotkey('2', "build_y", WID_ROT_ROAD_Y),
870 Hotkey('3', "autoroad", WID_ROT_AUTOROAD),
871 Hotkey('4', "demolish", WID_ROT_DEMOLISH),
872 Hotkey('5', "depot", WID_ROT_DEPOT),
873 Hotkey('6', "bus_station", WID_ROT_BUS_STATION),
874 Hotkey('7', "truck_station", WID_ROT_TRUCK_STATION),
875 Hotkey('8', "oneway", WID_ROT_ONE_WAY),
876 Hotkey('9', "waypoint", WID_ROT_BUILD_WAYPOINT),
877 Hotkey('B', "bridge", WID_ROT_BUILD_BRIDGE),
878 Hotkey('T', "tunnel", WID_ROT_BUILD_TUNNEL),
879 Hotkey('R', "remove", WID_ROT_REMOVE),
880 Hotkey('C', "convert", WID_ROT_CONVERT_ROAD),
881 }, RoadToolbarGlobalHotkeys};
882
883 static inline HotkeyList tram_hotkeys{"tramtoolbar", {
884 Hotkey('1', "build_x", WID_ROT_ROAD_X),
885 Hotkey('2', "build_y", WID_ROT_ROAD_Y),
886 Hotkey('3', "autoroad", WID_ROT_AUTOROAD),
887 Hotkey('4', "demolish", WID_ROT_DEMOLISH),
888 Hotkey('5', "depot", WID_ROT_DEPOT),
889 Hotkey('6', "bus_station", WID_ROT_BUS_STATION),
890 Hotkey('7', "truck_station", WID_ROT_TRUCK_STATION),
891 Hotkey('9', "waypoint", WID_ROT_BUILD_WAYPOINT),
892 Hotkey('B', "bridge", WID_ROT_BUILD_BRIDGE),
893 Hotkey('T', "tunnel", WID_ROT_BUILD_TUNNEL),
894 Hotkey('R', "remove", WID_ROT_REMOVE),
895 Hotkey('C', "convert", WID_ROT_CONVERT_ROAD),
896 }, TramToolbarGlobalHotkeys};
897};
898
899static constexpr NWidgetPart _nested_build_road_widgets[] = {
901 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
902 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetDataTip(STR_JUST_STRING2, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), SetTextStyle(TC_WHITE),
903 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
904 EndContainer(),
906 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_X),
907 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_X_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION),
908 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_Y),
909 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_Y_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION),
910 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_AUTOROAD),
911 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOROAD, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD),
912 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEMOLISH),
913 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
914 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEPOT),
915 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_DEPOT, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT),
916 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_WAYPOINT),
917 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_WAYPOINT, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD_TO_WAYPOINT),
918 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUS_STATION),
919 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_BUS_STATION, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION),
920 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_TRUCK_STATION),
921 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRUCK_BAY, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY),
922 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
923 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ONE_WAY),
924 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_ONE_WAY, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD),
925 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE),
926 SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE),
927 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL),
928 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL),
929 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_REMOVE),
930 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD),
931 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_CONVERT_ROAD),
932 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_CONVERT_ROAD, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD),
933 EndContainer(),
934};
935
936static WindowDesc _build_road_desc(
937 WDP_ALIGN_TOOLBAR, "toolbar_road", 0, 0,
940 _nested_build_road_widgets,
941 &BuildRoadToolbarWindow::road_hotkeys
942);
943
944static constexpr NWidgetPart _nested_build_tramway_widgets[] = {
946 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
947 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetDataTip(STR_JUST_STRING2, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), SetTextStyle(TC_WHITE),
948 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
949 EndContainer(),
951 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_X),
952 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRAMWAY_X_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION),
953 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_Y),
954 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRAMWAY_Y_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION),
955 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_AUTOROAD),
956 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOTRAM, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM),
957 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEMOLISH),
958 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
959 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEPOT),
960 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_DEPOT, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT),
961 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_WAYPOINT),
962 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_WAYPOINT, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM_TO_WAYPOINT),
963 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUS_STATION),
964 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_BUS_STATION, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION),
965 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_TRUCK_STATION),
966 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRUCK_BAY, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION),
967 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
968 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE),
969 SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE),
970 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL),
971 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL),
972 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_REMOVE),
973 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS),
974 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_CONVERT_ROAD),
975 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_CONVERT_ROAD, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM),
976 EndContainer(),
977};
978
979static WindowDesc _build_tramway_desc(
980 WDP_ALIGN_TOOLBAR, "toolbar_tramway", 0, 0,
983 _nested_build_tramway_widgets,
984 &BuildRoadToolbarWindow::tram_hotkeys
985);
986
995{
996 if (!Company::IsValidID(_local_company)) return nullptr;
997 if (!ValParamRoadType(roadtype)) return nullptr;
998
1000 _cur_roadtype = roadtype;
1001
1002 return AllocateWindowDescFront<BuildRoadToolbarWindow>(RoadTypeIsRoad(_cur_roadtype) ? _build_road_desc : _build_tramway_desc, TRANSPORT_ROAD);
1003}
1004
1005static constexpr NWidgetPart _nested_build_road_scen_widgets[] = {
1007 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1008 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetDataTip(STR_JUST_STRING2, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), SetTextStyle(TC_WHITE),
1009 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
1010 EndContainer(),
1012 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_X),
1013 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_X_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION),
1014 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_Y),
1015 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_Y_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION),
1016 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_AUTOROAD),
1017 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOROAD, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD),
1018 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEMOLISH),
1019 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
1020 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
1021 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ONE_WAY),
1022 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_ONE_WAY, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD),
1023 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE),
1024 SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE),
1025 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL),
1026 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL),
1027 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_REMOVE),
1028 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD),
1029 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_CONVERT_ROAD),
1030 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_CONVERT_ROAD, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD),
1031 EndContainer(),
1032};
1033
1034static WindowDesc _build_road_scen_desc(
1035 WDP_AUTO, "toolbar_road_scen", 0, 0,
1038 _nested_build_road_scen_widgets,
1039 &BuildRoadToolbarWindow::road_hotkeys
1040);
1041
1042static constexpr NWidgetPart _nested_build_tramway_scen_widgets[] = {
1044 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1045 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetDataTip(STR_JUST_STRING2, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), SetTextStyle(TC_WHITE),
1046 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
1047 EndContainer(),
1049 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_X),
1050 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRAMWAY_X_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION),
1051 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_Y),
1052 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRAMWAY_Y_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION),
1053 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_AUTOROAD),
1054 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOTRAM, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM),
1055 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEMOLISH),
1056 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
1057 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
1058 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE),
1059 SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE),
1060 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL),
1061 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL),
1062 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_REMOVE),
1063 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS),
1064 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_CONVERT_ROAD),
1065 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_CONVERT_ROAD, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM),
1066 EndContainer(),
1067};
1068
1069static WindowDesc _build_tramway_scen_desc(
1070 WDP_AUTO, "toolbar_tram_scen", 0, 0,
1073 _nested_build_tramway_scen_widgets,
1074 &BuildRoadToolbarWindow::tram_hotkeys
1075);
1076
1082{
1084 _cur_roadtype = roadtype;
1085
1086 return AllocateWindowDescFront<BuildRoadToolbarWindow>(RoadTypeIsRoad(_cur_roadtype) ? _build_road_scen_desc : _build_tramway_scen_desc, TRANSPORT_ROAD);
1087}
1088
1091 {
1092 this->CreateNestedTree();
1093
1094 this->LowerWidget(WID_BROD_DEPOT_NE + _road_depot_orientation);
1095 if (RoadTypeIsTram(_cur_roadtype)) {
1097 for (WidgetID i = WID_BROD_DEPOT_NE; i <= WID_BROD_DEPOT_NW; i++) {
1099 }
1100 }
1101
1103 }
1104
1106 {
1107 if (!IsInsideMM(widget, WID_BROD_DEPOT_NE, WID_BROD_DEPOT_NW + 1)) return;
1108
1111 }
1112
1113 void DrawWidget(const Rect &r, WidgetID widget) const override
1114 {
1115 if (!IsInsideMM(widget, WID_BROD_DEPOT_NE, WID_BROD_DEPOT_NW + 1)) return;
1116
1119 if (FillDrawPixelInfo(&tmp_dpi, ir)) {
1121 int x = (ir.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31);
1122 int y = (ir.Height() + ScaleSpriteTrad(48)) / 2 - ScaleSpriteTrad(31);
1123 DrawRoadDepotSprite(x, y, (DiagDirection)(widget - WID_BROD_DEPOT_NE + DIAGDIR_NE), _cur_roadtype);
1124 }
1125 }
1126
1127 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1128 {
1129 switch (widget) {
1130 case WID_BROD_DEPOT_NW:
1131 case WID_BROD_DEPOT_NE:
1132 case WID_BROD_DEPOT_SW:
1133 case WID_BROD_DEPOT_SE:
1134 this->RaiseWidget(WID_BROD_DEPOT_NE + _road_depot_orientation);
1135 _road_depot_orientation = (DiagDirection)(widget - WID_BROD_DEPOT_NE);
1136 this->LowerWidget(WID_BROD_DEPOT_NE + _road_depot_orientation);
1138 this->SetDirty();
1139 break;
1140
1141 default:
1142 break;
1143 }
1144 }
1145};
1146
1147static constexpr NWidgetPart _nested_build_road_depot_widgets[] = {
1149 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1150 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROD_CAPTION), SetDataTip(STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1151 EndContainer(),
1152 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
1155 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROD_DEPOT_NW), SetFill(0, 0), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
1156 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROD_DEPOT_SW), SetFill(0, 0), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
1157 EndContainer(),
1159 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROD_DEPOT_NE), SetFill(0, 0), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
1160 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROD_DEPOT_SE), SetFill(0, 0), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
1161 EndContainer(),
1162 EndContainer(),
1163 EndContainer(),
1164};
1165
1166static WindowDesc _build_road_depot_desc(
1167 WDP_AUTO, nullptr, 0, 0,
1170 _nested_build_road_depot_widgets
1171);
1172
1173static void ShowRoadDepotPicker(Window *parent)
1174{
1175 new BuildRoadDepotWindow(_build_road_depot_desc, parent);
1176}
1177
1178template <RoadStopType roadstoptype>
1180public:
1182
1183 StringID GetClassTooltip() const override;
1184 StringID GetTypeTooltip() const override;
1185
1186 bool IsActive() const override
1187 {
1188 for (const auto &cls : RoadStopClass::Classes()) {
1189 if (IsWaypointClass(cls)) continue;
1190 for (const auto *spec : cls.Specs()) {
1191 if (spec == nullptr) continue;
1192 if (roadstoptype == ROADSTOP_TRUCK && spec->stop_type != ROADSTOPTYPE_FREIGHT && spec->stop_type != ROADSTOPTYPE_ALL) continue;
1193 if (roadstoptype == ROADSTOP_BUS && spec->stop_type != ROADSTOPTYPE_PASSENGER && spec->stop_type != ROADSTOPTYPE_ALL) continue;
1194 return true;
1195 }
1196 }
1197 return false;
1198 }
1199
1200 static bool IsClassChoice(const RoadStopClass &cls)
1201 {
1202 return !IsWaypointClass(cls) && GetIfClassHasNewStopsByType(&cls, roadstoptype, _cur_roadtype);
1203 }
1204
1205 bool HasClassChoice() const override
1206 {
1207 return std::ranges::count_if(RoadStopClass::Classes(), IsClassChoice);
1208 }
1209
1210 int GetSelectedClass() const override { return _roadstop_gui.sel_class; }
1211 void SetSelectedClass(int id) const override { _roadstop_gui.sel_class = this->GetClassIndex(id); }
1212
1213 StringID GetClassName(int id) const override
1214 {
1215 const auto *rsc = this->GetClass(id);
1216 if (!IsClassChoice(*rsc)) return INVALID_STRING_ID;
1217 return rsc->name;
1218 }
1219
1220 int GetSelectedType() const override { return _roadstop_gui.sel_type; }
1221 void SetSelectedType(int id) const override { _roadstop_gui.sel_type = id; }
1222
1223 StringID GetTypeName(int cls_id, int id) const override
1224 {
1225 const auto *spec = this->GetSpec(cls_id, id);
1226 if (!IsRoadStopEverAvailable(spec, roadstoptype == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK)) return INVALID_STRING_ID;
1227 return (spec == nullptr) ? STR_STATION_CLASS_DFLT_ROADSTOP : spec->name;
1228 }
1229
1230 bool IsTypeAvailable(int cls_id, int id) const override
1231 {
1232 const auto *spec = this->GetSpec(cls_id, id);
1233 return IsRoadStopAvailable(spec, roadstoptype == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK);
1234 }
1235
1236 void DrawType(int x, int y, int cls_id, int id) const override
1237 {
1238 const auto *spec = this->GetSpec(cls_id, id);
1239 if (spec == nullptr) {
1240 StationPickerDrawSprite(x, y, roadstoptype == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK, INVALID_RAILTYPE, _cur_roadtype, _roadstop_gui.orientation);
1241 } else {
1242 DiagDirection orientation = _roadstop_gui.orientation;
1243 if (orientation < DIAGDIR_END && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY)) orientation = DIAGDIR_END;
1244 DrawRoadStopTile(x, y, _cur_roadtype, spec, roadstoptype == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK, (uint8_t)orientation);
1245 }
1246 }
1247
1248 void FillUsedItems(std::set<PickerItem> &items) override
1249 {
1250 for (const Station *st : Station::Iterate()) {
1251 if (st->owner != _local_company) continue;
1252 if (roadstoptype == ROADSTOP_TRUCK && !(st->facilities & FACIL_TRUCK_STOP)) continue;
1253 if (roadstoptype == ROADSTOP_BUS && !(st->facilities & FACIL_BUS_STOP)) continue;
1254 items.insert({0, 0, ROADSTOP_CLASS_DFLT, 0}); // We would need to scan the map to find out if default is used.
1255 for (const auto &sm : st->roadstop_speclist) {
1256 if (sm.spec == nullptr) continue;
1257 if (roadstoptype == ROADSTOP_TRUCK && sm.spec->stop_type != ROADSTOPTYPE_FREIGHT && sm.spec->stop_type != ROADSTOPTYPE_ALL) continue;
1258 if (roadstoptype == ROADSTOP_BUS && sm.spec->stop_type != ROADSTOPTYPE_PASSENGER && sm.spec->stop_type != ROADSTOPTYPE_ALL) continue;
1259 items.insert({sm.grfid, sm.localidx, sm.spec->class_index, sm.spec->index});
1260 }
1261 }
1262 }
1263};
1264
1265template <> StringID RoadStopPickerCallbacks<ROADSTOP_BUS>::GetClassTooltip() const { return STR_PICKER_ROADSTOP_BUS_CLASS_TOOLTIP; }
1266template <> StringID RoadStopPickerCallbacks<ROADSTOP_BUS>::GetTypeTooltip() const { return STR_PICKER_ROADSTOP_BUS_TYPE_TOOLTIP; }
1267
1268template <> StringID RoadStopPickerCallbacks<ROADSTOP_TRUCK>::GetClassTooltip() const { return STR_PICKER_ROADSTOP_TRUCK_CLASS_TOOLTIP; }
1269template <> StringID RoadStopPickerCallbacks<ROADSTOP_TRUCK>::GetTypeTooltip() const { return STR_PICKER_ROADSTOP_TRUCK_TYPE_TOOLTIP; }
1270
1271static RoadStopPickerCallbacks<ROADSTOP_BUS> _bus_callback_instance("fav_passenger_roadstops");
1272static RoadStopPickerCallbacks<ROADSTOP_TRUCK> _truck_callback_instance("fav_freight_roadstops");
1273
1274static PickerCallbacks &GetRoadStopPickerCallbacks(RoadStopType rs)
1275{
1276 return rs == ROADSTOP_BUS ? static_cast<PickerCallbacks &>(_bus_callback_instance) : static_cast<PickerCallbacks &>(_truck_callback_instance);
1277}
1278
1280private:
1282
1283 void CheckOrientationValid()
1284 {
1285 const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui.sel_class)->GetSpec(_roadstop_gui.sel_type);
1286
1287 /* Raise and lower to ensure the correct widget is lowered after changing displayed orientation plane. */
1288 if (RoadTypeIsRoad(_cur_roadtype)) {
1289 this->RaiseWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
1290 this->GetWidget<NWidgetStacked>(WID_BROS_AVAILABLE_ORIENTATIONS)->SetDisplayedPlane((spec != nullptr && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY)) ? 1 : 0);
1291 this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
1292 }
1293
1294 if (_roadstop_gui.orientation >= DIAGDIR_END) return;
1295
1296 if (spec != nullptr && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY)) {
1297 this->RaiseWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
1298 _roadstop_gui.orientation = DIAGDIR_END;
1299 this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
1300 this->SetDirty();
1302 }
1303 }
1304
1305public:
1306 BuildRoadStationWindow(WindowDesc &desc, Window *parent, RoadStopType rs) : PickerWindow(desc, parent, TRANSPORT_ROAD, GetRoadStopPickerCallbacks(rs))
1307 {
1309
1310 /* Trams don't have non-drivethrough stations */
1311 if (RoadTypeIsTram(_cur_roadtype) && _roadstop_gui.orientation < DIAGDIR_END) {
1312 _roadstop_gui.orientation = DIAGDIR_END;
1313 }
1314 this->ConstructWindow();
1315
1316 const RoadTypeInfo *rti = GetRoadTypeInfo(_cur_roadtype);
1318
1319 for (WidgetID i = RoadTypeIsTram(_cur_roadtype) ? WID_BROS_STATION_X : WID_BROS_STATION_NE; i < WID_BROS_LT_OFF; i++) {
1320 this->GetWidget<NWidgetCore>(i)->tool_tip = rti->strings.picker_tooltip[rs];
1321 }
1322
1323 this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
1324 this->LowerWidget(WID_BROS_LT_OFF + _settings_client.gui.station_show_coverage);
1325
1327 }
1328
1329 void Close([[maybe_unused]] int data = 0) override
1330 {
1332 this->PickerWindow::Close();
1333 }
1334
1335 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
1336 {
1338
1339 if (gui_scope) {
1340 this->CheckOrientationValid();
1341 }
1342 }
1343
1344 void OnPaint() override
1345 {
1346 this->DrawWidgets();
1347
1350 SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
1351 } else {
1352 SetTileSelectSize(1, 1);
1353 }
1354
1355 if (this->IsShaded()) return;
1356
1357 /* 'Accepts' and 'Supplies' texts. */
1359 Rect r = this->GetWidget<NWidgetBase>(WID_BROS_ACCEPTANCE)->GetCurrentRect();
1360 int top = r.top;
1362 top = DrawStationCoverageAreaText(r.left, r.right, top, sct, rad, true);
1363 /* Resize background if the window is too small.
1364 * Never make the window smaller to avoid oscillating if the size change affects the acceptance.
1365 * (This is the case, if making the window bigger moves the mouse into the window.) */
1366 if (top > r.bottom) {
1367 this->coverage_height += top - r.bottom;
1368 this->ReInit();
1369 }
1370 }
1371
1373 {
1374 switch (widget) {
1379 case WID_BROS_STATION_X:
1380 case WID_BROS_STATION_Y:
1383 break;
1384
1386 size.height = this->coverage_height;
1387 break;
1388
1389 default:
1390 this->PickerWindow::UpdateWidgetSize(widget, size, padding, fill, resize);
1391 break;
1392 }
1393 }
1394
1399 {
1400 switch (window_class) {
1401 case WC_BUS_STATION: return STATION_BUS;
1402 case WC_TRUCK_STATION: return STATION_TRUCK;
1403 default: NOT_REACHED();
1404 }
1405 }
1406
1407 void DrawWidget(const Rect &r, WidgetID widget) const override
1408 {
1409 switch (widget) {
1414 case WID_BROS_STATION_X:
1415 case WID_BROS_STATION_Y: {
1417 const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui.sel_class)->GetSpec(_roadstop_gui.sel_type);
1420 if (FillDrawPixelInfo(&tmp_dpi, ir)) {
1422 int x = (ir.Width() - ScaleSpriteTrad(PREVIEW_WIDTH)) / 2 + ScaleSpriteTrad(PREVIEW_LEFT);
1423 int y = (ir.Height() + ScaleSpriteTrad(PREVIEW_HEIGHT)) / 2 - ScaleSpriteTrad(PREVIEW_BOTTOM);
1424 if (spec == nullptr) {
1425 StationPickerDrawSprite(x, y, st, INVALID_RAILTYPE, _cur_roadtype, widget - WID_BROS_STATION_NE);
1426 } else {
1427 DrawRoadStopTile(x, y, _cur_roadtype, spec, st, widget - WID_BROS_STATION_NE);
1428 }
1429 }
1430 break;
1431 }
1432
1433 default:
1434 this->PickerWindow::DrawWidget(r, widget);
1435 break;
1436 }
1437 }
1438
1439 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1440 {
1441 switch (widget) {
1446 case WID_BROS_STATION_X:
1447 case WID_BROS_STATION_Y:
1448 if (widget < WID_BROS_STATION_X) {
1449 const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui.sel_class)->GetSpec(_roadstop_gui.sel_type);
1450 if (spec != nullptr && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY)) return;
1451 }
1452 this->RaiseWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
1453 _roadstop_gui.orientation = (DiagDirection)(widget - WID_BROS_STATION_NE);
1454 this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
1456 this->SetDirty();
1458 break;
1459
1460 case WID_BROS_LT_OFF:
1461 case WID_BROS_LT_ON:
1466 this->SetDirty();
1467 SetViewportCatchmentStation(nullptr, true);
1468 break;
1469
1470 default:
1471 this->PickerWindow::OnClick(pt, widget, click_count);
1472 break;
1473 }
1474 }
1475
1476 void OnRealtimeTick([[maybe_unused]] uint delta_ms) override
1477 {
1479 }
1480
1481 static inline HotkeyList road_hotkeys{"buildroadstop", {
1482 Hotkey('F', "focus_filter_box", PCWHK_FOCUS_FILTER_BOX),
1483 }};
1484
1485 static inline HotkeyList tram_hotkeys{"buildtramstop", {
1486 Hotkey('F', "focus_filter_box", PCWHK_FOCUS_FILTER_BOX),
1487 }};
1488};
1489
1493 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1494 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROS_CAPTION),
1495 NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
1496 NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN),
1497 EndContainer(),
1501 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
1504 /* 6-orientation plane. */
1508 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NW), SetFill(0, 0), EndContainer(),
1509 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NE), SetFill(0, 0), EndContainer(),
1510 EndContainer(),
1511 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetFill(0, 0), EndContainer(),
1512 EndContainer(),
1515 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SW), SetFill(0, 0), EndContainer(),
1516 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SE), SetFill(0, 0), EndContainer(),
1517 EndContainer(),
1518 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetFill(0, 0), EndContainer(),
1519 EndContainer(),
1520 EndContainer(),
1521 /* 2-orientation plane. */
1524 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetFill(0, 0), EndContainer(),
1525 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetFill(0, 0), EndContainer(),
1526 EndContainer(),
1527 EndContainer(),
1528 EndContainer(),
1529 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0),
1531 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_OFF), SetMinimalSize(60, 12),
1532 SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
1533 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_ON), SetMinimalSize(60, 12),
1534 SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
1535 EndContainer(),
1536 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BROS_ACCEPTANCE), SetFill(1, 1), SetResize(1, 0), SetMinimalTextLines(2, 0),
1537 EndContainer(),
1538 EndContainer(),
1539 EndContainer(),
1541 EndContainer(),
1542};
1543
1544static WindowDesc _road_station_picker_desc(
1545 WDP_AUTO, "build_station_road", 0, 0,
1549 &BuildRoadStationWindow::road_hotkeys
1550);
1551
1555 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1556 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROS_CAPTION),
1557 NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
1558 NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN),
1559 EndContainer(),
1563 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
1566 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetFill(0, 0), EndContainer(),
1567 NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetFill(0, 0), EndContainer(),
1568 EndContainer(),
1569 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0),
1571 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_OFF), SetMinimalSize(60, 12),
1572 SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
1573 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_ON), SetMinimalSize(60, 12),
1574 SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
1575 EndContainer(),
1576 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BROS_ACCEPTANCE), SetFill(1, 1), SetResize(1, 0), SetMinimalTextLines(2, 0),
1577 EndContainer(),
1578 EndContainer(),
1579 EndContainer(),
1581 EndContainer(),
1582};
1583
1584static WindowDesc _tram_station_picker_desc(
1585 WDP_AUTO, "build_station_tram", 0, 0,
1589 &BuildRoadStationWindow::tram_hotkeys
1590);
1591
1592static void ShowRVStationPicker(Window *parent, RoadStopType rs)
1593{
1594 new BuildRoadStationWindow(RoadTypeIsRoad(_cur_roadtype) ? _road_station_picker_desc : _tram_station_picker_desc, parent, rs);
1595}
1596
1598public:
1600
1601 StringID GetClassTooltip() const override { return STR_PICKER_WAYPOINT_CLASS_TOOLTIP; }
1602 StringID GetTypeTooltip() const override { return STR_PICKER_WAYPOINT_TYPE_TOOLTIP; }
1603
1604 bool IsActive() const override
1605 {
1606 for (const auto &cls : RoadStopClass::Classes()) {
1607 if (!IsWaypointClass(cls)) continue;
1608 for (const auto *spec : cls.Specs()) {
1609 if (spec != nullptr) return true;
1610 }
1611 }
1612 return false;
1613 }
1614
1615 bool HasClassChoice() const override
1616 {
1617 return std::ranges::count_if(RoadStopClass::Classes(), IsWaypointClass) > 1;
1618 }
1619
1620 void Close(int) override { ResetObjectToPlace(); }
1621 int GetSelectedClass() const override { return _waypoint_gui.sel_class; }
1622 void SetSelectedClass(int id) const override { _waypoint_gui.sel_class = this->GetClassIndex(id); }
1623
1624 StringID GetClassName(int id) const override
1625 {
1626 const auto *sc = GetClass(id);
1627 if (!IsWaypointClass(*sc)) return INVALID_STRING_ID;
1628 return sc->name;
1629 }
1630
1631 int GetSelectedType() const override { return _waypoint_gui.sel_type; }
1632 void SetSelectedType(int id) const override { _waypoint_gui.sel_type = id; }
1633
1634 StringID GetTypeName(int cls_id, int id) const override
1635 {
1636 const auto *spec = this->GetSpec(cls_id, id);
1637 return (spec == nullptr) ? STR_STATION_CLASS_WAYP_WAYPOINT : spec->name;
1638 }
1639
1640 bool IsTypeAvailable(int cls_id, int id) const override
1641 {
1642 return IsRoadStopAvailable(this->GetSpec(cls_id, id), STATION_ROADWAYPOINT);
1643 }
1644
1645 void DrawType(int x, int y, int cls_id, int id) const override
1646 {
1647 const auto *spec = this->GetSpec(cls_id, id);
1648 if (spec == nullptr) {
1649 StationPickerDrawSprite(x, y, STATION_ROADWAYPOINT, INVALID_RAILTYPE, _cur_roadtype, RSV_DRIVE_THROUGH_X);
1650 } else {
1651 DrawRoadStopTile(x, y, _cur_roadtype, spec, STATION_ROADWAYPOINT, RSV_DRIVE_THROUGH_X);
1652 }
1653 }
1654
1655 void FillUsedItems(std::set<PickerItem> &items) override
1656 {
1657 for (const Waypoint *wp : Waypoint::Iterate()) {
1658 if (wp->owner != _local_company || !HasBit(wp->waypoint_flags, WPF_ROAD)) continue;
1659 items.insert({0, 0, ROADSTOP_CLASS_WAYP, 0}); // We would need to scan the map to find out if default is used.
1660 for (const auto &sm : wp->roadstop_speclist) {
1661 if (sm.spec == nullptr) continue;
1662 items.insert({sm.grfid, sm.localidx, sm.spec->class_index, sm.spec->index});
1663 }
1664 }
1665 }
1666
1667 static RoadWaypointPickerCallbacks instance;
1668};
1669/* static */ RoadWaypointPickerCallbacks RoadWaypointPickerCallbacks::instance;
1670
1672 BuildRoadWaypointWindow(WindowDesc &desc, Window *parent) : PickerWindow(desc, parent, TRANSPORT_ROAD, RoadWaypointPickerCallbacks::instance)
1673 {
1674 this->ConstructWindow();
1675 this->InvalidateData();
1676 }
1677
1678 static inline HotkeyList hotkeys{"buildroadwaypoint", {
1679 Hotkey('F', "focus_filter_box", PCWHK_FOCUS_FILTER_BOX),
1680 }};
1681};
1682
1686 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1687 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_WAYPOINT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1688 NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
1689 NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN),
1690 EndContainer(),
1694 EndContainer(),
1695};
1696
1697static WindowDesc _build_road_waypoint_desc(
1698 WDP_AUTO, "build_road_waypoint", 0, 0,
1702 &BuildRoadWaypointWindow::hotkeys
1703);
1704
1705static void ShowBuildRoadWaypointPicker(Window *parent)
1706{
1707 if (!RoadWaypointPickerCallbacks::instance.IsActive()) return;
1708 new BuildRoadWaypointWindow(_build_road_waypoint_desc, parent);
1709}
1710
1711void InitializeRoadGui()
1712{
1713 _road_depot_orientation = DIAGDIR_NW;
1714 _roadstop_gui.orientation = DIAGDIR_NW;
1717}
1718
1723{
1725 if (w != nullptr) w->ModifyRoadType(_cur_roadtype);
1726}
1727
1728DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement, bool all_option)
1729{
1730 RoadTypes used_roadtypes;
1731 RoadTypes avail_roadtypes;
1732
1734
1735 /* Find the used roadtypes. */
1736 if (for_replacement) {
1737 avail_roadtypes = GetCompanyRoadTypes(c->index, false);
1738 used_roadtypes = GetRoadTypes(false);
1739 } else {
1740 avail_roadtypes = c->avail_roadtypes;
1741 used_roadtypes = GetRoadTypes(true);
1742 }
1743
1744 /* Filter listed road types */
1745 if (!HasBit(rtts, RTT_ROAD)) used_roadtypes &= _roadtypes_type;
1746 if (!HasBit(rtts, RTT_TRAM)) used_roadtypes &= ~_roadtypes_type;
1747
1748 DropDownList list;
1749
1750 if (all_option) {
1751 list.push_back(MakeDropDownListStringItem(STR_REPLACE_ALL_ROADTYPE, INVALID_ROADTYPE));
1752 }
1753
1754 Dimension d = { 0, 0 };
1755 /* Get largest icon size, to ensure text is aligned on each menu item. */
1756 if (!for_replacement) {
1757 for (const auto &rt : _sorted_roadtypes) {
1758 if (!HasBit(used_roadtypes, rt)) continue;
1759 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
1761 }
1762 }
1763
1764 for (const auto &rt : _sorted_roadtypes) {
1765 /* If it's not used ever, don't show it to the user. */
1766 if (!HasBit(used_roadtypes, rt)) continue;
1767
1768 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
1769
1770 SetDParam(0, rti->strings.menu_text);
1771 SetDParam(1, rti->max_speed / 2);
1772 if (for_replacement) {
1773 list.push_back(MakeDropDownListStringItem(rti->strings.replace_text, rt, !HasBit(avail_roadtypes, rt)));
1774 } else {
1775 StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING;
1776 list.push_back(MakeDropDownListIconItem(d, rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt)));
1777 }
1778 }
1779
1780 if (list.empty()) {
1781 /* Empty dropdowns are not allowed */
1782 list.push_back(MakeDropDownListStringItem(STR_NONE, INVALID_ROADTYPE, true));
1783 }
1784
1785 return list;
1786}
1787
1788DropDownList GetScenRoadTypeDropDownList(RoadTramTypes rtts)
1789{
1790 RoadTypes avail_roadtypes = GetRoadTypes(false);
1791 avail_roadtypes = AddDateIntroducedRoadTypes(avail_roadtypes, TimerGameCalendar::date);
1792 RoadTypes used_roadtypes = GetRoadTypes(true);
1793
1794 /* Filter listed road types */
1795 if (!HasBit(rtts, RTT_ROAD)) used_roadtypes &= _roadtypes_type;
1796 if (!HasBit(rtts, RTT_TRAM)) used_roadtypes &= ~_roadtypes_type;
1797
1798 DropDownList list;
1799
1800 /* If it's not used ever, don't show it to the user. */
1801 Dimension d = { 0, 0 };
1802 for (const auto &rt : _sorted_roadtypes) {
1803 if (!HasBit(used_roadtypes, rt)) continue;
1804 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
1806 }
1807 for (const auto &rt : _sorted_roadtypes) {
1808 if (!HasBit(used_roadtypes, rt)) continue;
1809
1810 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
1811
1812 SetDParam(0, rti->strings.menu_text);
1813 SetDParam(1, rti->max_speed / 2);
1814 StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING;
1815 list.push_back(MakeDropDownListIconItem(d, rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt)));
1816 }
1817
1818 if (list.empty()) {
1819 /* Empty dropdowns are not allowed */
1820 list.push_back(MakeDropDownListStringItem(STR_NONE, -1, true));
1821 }
1822
1823 return list;
1824}
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
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:100
Class for PickerClassWindow to collect information and retain state.
Definition picker_gui.h:37
const std::string ini_group
Ini Group for saving favourites.
Definition picker_gui.h:91
Base class for windows opened from a toolbar.
Definition window_gui.h:986
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:165
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:185
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:163
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:166
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:164
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.
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:105
StringID replace_text
Text used in the autoreplace GUI.
Definition road.h:107
StringID picker_title[2]
Title for the station picker for bus or truck stations.
Definition road.h:117
CursorID autoroad
Cursor for autorail tool.
Definition road.h:96
StringID picker_tooltip[2]
Tooltip for the station picker for bus or truck stations.
Definition road.h:118
struct RoadTypeInfo::@29 strings
Strings associated with the rail type.
StringID err_build_road
Building a normal piece of road.
Definition road.h:110
StringID err_remove_road
Removing a normal piece of road.
Definition road.h:111
CursorID depot
Cursor for building a depot.
Definition road.h:97
CursorID road_nwse
Cursor for building rail in Y direction.
Definition road.h:95
uint16_t max_speed
Maximum speed for vehicles travelling on this road type.
Definition road.h:142
StringID toolbar_caption
Caption in the construction toolbar GUI for this rail type.
Definition road.h:104
SpriteID build_y_road
button for building single rail in Y direction
Definition road.h:86
CursorID tunnel
Cursor for building a tunnel.
Definition road.h:98
SpriteID auto_road
button for the autoroad construction
Definition road.h:87
struct RoadTypeInfo::@27 gui_sprites
struct containing the sprites for the road GUI.
SpriteID convert_road
button for converting road types
Definition road.h:90
CursorID road_swne
Cursor for building rail in X direction.
Definition road.h:94
StringID err_convert_road
Converting a road type.
Definition road.h:115
StringID err_depot
Building a depot.
Definition road.h:112
SpriteID build_x_road
button for building single rail in X direction
Definition road.h:85
SpriteID build_depot
button for building depots
Definition road.h:88
SpriteID build_tunnel
button for building a tunnel
Definition road.h:89
StringID err_build_station[2]
Building a bus or truck station.
Definition road.h:113
StringID err_remove_station[2]
Removing of a bus or truck station.
Definition road.h:114
StringID GetTypeTooltip() const override
Get the tooltip string for the type grid.
int GetSelectedType() const override
Get the selected 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:28
int vsep_normal
Normal vertical spacing.
Definition window_gui.h:60
RectPadding fullbevel
Always-scaled bevel thickness.
Definition window_gui.h:41
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition window_gui.h:96
Functions related to commands.
static constexpr DoCommandFlag CommandFlagsToDCFlags(CommandFlags cmd_flags)
Extracts the DC flags needed for DoCommand from the flags returned by GetCommandFlags.
@ DC_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.
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:922
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:1548
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:209
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 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 SetDataTip(uint32_t data, StringID tip)
Widget part function for setting the data 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 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:940
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:567
static debug_inline TileIndex TileVirtXY(uint x, uint y)
Get a tile from the virtual XY-coordinate.
Definition map_func.h:404
constexpr bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
@ CBID_STATION_AVAILABILITY
Determine whether a newstation should be made available to build.
@ CBM_ROAD_STOP_AVAIL
Availability of road stop in construction window.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
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.
@ RSV_DRIVE_THROUGH_X
Drive through road stop, X axis.
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.
@ RSF_NO_AUTO_ROAD_CONNECTION
No auto road connection.
@ RSF_DRIVE_THROUGH_ONLY
Stop is drive-through only.
@ RSF_BUILD_MENU_ROAD_ONLY
Only show in the road build menu (not tram).
@ RSF_BUILD_MENU_TRAM_ONLY
Only show in the tram build menu (not road).
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:227
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:194
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:228
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:295
static bool IsRoadStopAvailable(const RoadStopSpec *spec, StationType type)
Check whether a road stop type can be built.
Definition road_gui.cpp:101
static void PlaceRoad_Bridge(TileIndex tile, Window *w)
Callback to start placing a bridge.
Definition road_gui.cpp:123
static void PlaceRoad_BusStation(TileIndex tile)
Callback for placing a bus station.
Definition road_gui.cpp:277
static void PlaceRoad_Waypoint(TileIndex tile)
Place a road waypoint.
Definition road_gui.cpp:254
static void ToggleRoadButton_Remove(Window *w)
Toggles state of the Remove button of Build road toolbar.
Definition road_gui.cpp:315
static RoadWaypointPickerSelection _waypoint_gui
Settings of the road waypoint picker.
Definition road_gui.cpp:73
static bool RoadToolbar_CtrlChanged(Window *w)
Updates the Remove button because of Ctrl state change.
Definition road_gui.cpp:328
Window * ShowBuildRoadToolbar(RoadType roadtype)
Open the build road toolbar window.
Definition road_gui.cpp:994
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:162
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:57
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:56
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:1508
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.
void CheckRedrawStationCoverage(const Window *w)
Check whether we need to redraw the station coverage text.
int DrawStationCoverageAreaText(int left, int right, int top, StationCoverageType sct, int rad, bool supplies)
Calculates and draws the accepted or supplied cargo around the selected tile(s)
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:20
@ SCT_NON_PASSENGERS_ONLY
Draw all non-passenger class cargoes.
Definition station_gui.h:22
@ SCT_PASSENGERS_ONLY
Draw only passenger class cargoes.
Definition station_gui.h:21
RoadStopType
Types of RoadStops.
@ ROADSTOP_BUS
A standard stop for buses.
@ ROADSTOP_TRUCK
A standard stop for trucks.
@ FACIL_BUS_STOP
Station with bus stops.
@ FACIL_TRUCK_STOP
Station with truck 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.
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
Definition strings.cpp:104
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:344
void OnPlaceObjectAbort() override
The user cancelled a tile highlight mode that has been set.
Definition road_gui.cpp:668
void ModifyRoadType(RoadType roadtype)
Switch to another road type.
Definition road_gui.cpp:436
void OnRealtimeTick(uint delta_ms) override
Called periodically.
Definition road_gui.cpp:823
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:689
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:365
static EventState RoadTramToolbarGlobalHotkeys(int hotkey, RoadType last_build, RoadTramType rtt)
Handler for global hotkeys of the BuildRoadToolbarWindow.
Definition road_gui.cpp:834
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:606
EventState OnHotkey(int hotkey) override
A hotkey has been pressed.
Definition road_gui.cpp:600
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:811
void OnInit() override
Notification that the nested widget tree gets initialized.
Definition road_gui.cpp:418
int last_started_action
Last started user action.
Definition road_gui.cpp:346
RoadType roadtype
Road type to build.
Definition road_gui.cpp:345
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:728
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:511
void SetStringParameters(WidgetID widget) const override
Initialize string parameters for a widget.
Definition road_gui.cpp:442
void UpdateOptionWidgetStatus(RoadToolbarWidgets clicked_widget)
Update the remove button lowered state of the road toolbar.
Definition road_gui.cpp:461
EventState OnCTRLStateChange() override
The state of the control key has changed.
Definition road_gui.cpp:817
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition road_gui.cpp:377
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:157
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.
Tindex index
Index of this pool item.
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
static Titem * Get(size_t index)
Returns Titem with given index.
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:76
DiagDirection orientation
Selected orientation of the road stop.
Definition road_gui.cpp:78
uint16_t sel_type
Selected road stop type within the class.
Definition road_gui.cpp:77
Road stop specification.
GRFFilePropsBase< NUM_CARGO+3 > grf_prop
Properties related the the grf file.
RoadStopClassID sel_class
Selected road waypoint class.
Definition road_gui.cpp:70
uint16_t sel_type
Selected road waypoint type within the class.
Definition road_gui.cpp:71
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:159
Data structure for an opened window.
Definition window_gui.h:273
void ReInit(int rx=0, int ry=0, bool reposition=false)
Re-initialize a window, and optionally change its size.
Definition window.cpp:952
virtual void Close(int data=0)
Hide the window and all its child windows, and mark them for a later deletion.
Definition window.cpp:1047
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1733
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:732
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing)
Definition window.cpp:3159
Window * parent
Parent window.
Definition window_gui.h:328
void RaiseWidget(WidgetID widget_index)
Marks a widget as raised.
Definition window_gui.h:475
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:551
ResizeInfo resize
Resize information.
Definition window_gui.h:314
void DisableWidget(WidgetID widget_index)
Sets a widget to disabled.
Definition window_gui.h:397
void SetWidgetsDisabledState(bool disab_stat, Args... widgets)
Sets the enabled/disabled status of a list of widgets.
Definition window_gui.h:521
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1723
WindowClass window_class
Window class.
Definition window_gui.h:301
bool IsWidgetLowered(WidgetID widget_index) const
Gets the lowered state of a widget.
Definition window_gui.h:497
bool IsWidgetDisabled(WidgetID widget_index) const
Gets the enabled/disabled status of a widget.
Definition window_gui.h:416
void RaiseButtons(bool autoraise=false)
Raise the buttons of the window.
Definition window.cpp:525
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition window_gui.h:447
bool IsShaded() const
Is window shaded currently?
Definition window_gui.h:563
int top
y position of top edge of the window
Definition window_gui.h:310
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:836
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:977
void LowerWidget(WidgetID widget_index)
Marks a widget as lowered.
Definition window_gui.h:466
virtual EventState OnHotkey(int hotkey)
A hotkey has been pressed.
Definition window.cpp:565
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:387
void ToggleWidgetLoweredState(WidgetID widget_index)
Invert the lowered/raised status of a widget.
Definition window_gui.h:456
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:302
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:1922
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.
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.
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
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:35
@ WWT_IMGBTN
(Toggle) Button with image
Definition widget_type.h:52
@ WWT_LABEL
Centered label.
Definition widget_type.h:57
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:75
@ WWT_TEXTBTN
(Toggle) Button with text
Definition widget_type.h:55
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:50
@ WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition widget_type.h:66
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition widget_type.h:64
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition widget_type.h:61
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:77
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:69
@ WWT_EMPTY
Empty widget, place holder to reserve space in widget tree.
Definition widget_type.h:48
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition widget_type.h:65
@ NWID_HORIZONTAL_LTR
Horizontal container that doesn't change the order of the widgets for RTL languages.
Definition widget_type.h:76
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:80
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:1140
void CloseWindowByClass(WindowClass cls, int data)
Close all windows of a given class.
Definition window.cpp:1152
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition window.cpp:1098
Window functions not directly related to making/drawing windows.
Functions, definitions and such used only by the GUI.
@ WDF_CONSTRUCTION
This window is used for construction; close it whenever changing company.
Definition window_gui.h:203
@ WDP_AUTO
Find a place automatically.
Definition window_gui.h:147
@ WDP_ALIGN_TOOLBAR
Align toward the toolbar.
Definition window_gui.h:149
int WidgetID
Widget ID.
Definition window_type.h:18
int32_t WindowNumber
Number to differentiate different windows of the same class.
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:44
@ WC_SCEN_BUILD_TOOLBAR
Scenario build toolbar; Window numbers:
Definition window_type.h:80
@ WC_BUILD_TOOLBAR
Build toolbar; Window numbers:
Definition window_type.h:73
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:45
@ 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