OpenTTD Source 20260711-master-g3fb3006dff
rail_gui.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#include "stdafx.h"
11#include "gui.h"
12#include "station_base.h"
13#include "waypoint_base.h"
14#include "window_gui.h"
15#include "station_gui.h"
16#include "terraform_gui.h"
17#include "viewport_func.h"
18#include "command_func.h"
19#include "waypoint_func.h"
20#include "newgrf_badge.h"
21#include "newgrf_badge_gui.h"
22#include "newgrf_station.h"
23#include "company_base.h"
24#include "strings_func.h"
25#include "window_func.h"
26#include "sound_func.h"
27#include "company_func.h"
28#include "dropdown_type.h"
29#include "dropdown_func.h"
30#include "tunnelbridge.h"
31#include "tilehighlight_func.h"
33#include "hotkeys.h"
34#include "engine_base.h"
35#include "vehicle_func.h"
36#include "zoom_func.h"
37#include "rail_gui.h"
38#include "toolbar_gui.h"
39#include "station_cmd.h"
40#include "tunnelbridge_cmd.h"
41#include "waypoint_cmd.h"
42#include "rail_cmd.h"
43#include "timer/timer.h"
45#include "picker_gui.h"
46
47#include "station_map.h"
48#include "tunnelbridge_map.h"
49
50#include "widgets/rail_widget.h"
51
52#include "table/strings.h"
53
54#include "safeguards.h"
55
56
63
69
76
77
78static void HandleStationPlacement(TileIndex start, TileIndex end);
79static void ShowBuildTrainDepotPicker(Window *parent);
80static void ShowBuildWaypointPicker(Window *parent);
81static Window *ShowStationBuilder(Window *parent);
82static void ShowSignalBuilder(Window *parent);
83
89static bool IsStationAvailable(const StationSpec *statspec)
90{
91 if (statspec == nullptr || !statspec->callback_mask.Test(StationCallbackMask::Avail)) return true;
92
93 uint16_t cb_res = GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, nullptr, INVALID_TILE);
94 if (cb_res == CALLBACK_FAILED) return true;
95
97}
98
99void CcPlaySound_CONSTRUCTION_RAIL(Commands, const CommandCost &result, TileIndex tile)
100{
101 if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile);
102}
103
104static void GenericPlaceRail(TileIndex tile, Track track)
105{
107 Command<Commands::RemoveRail>::Post(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL,
108 tile, track);
109 } else {
110 Command<Commands::BuildRail>::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL,
111 tile, _cur_railtype, track, _settings_client.gui.auto_remove_signals);
112 }
113}
114
123{
124 if (GetRailTileType(tile) == RailTileType::Depot) return;
125 if (GetRailTileType(tile) == RailTileType::Signals && !_settings_client.gui.auto_remove_signals) return;
126 if (!GetTrackBits(tile).Any(DiagdirReachesTracks(dir))) return;
127
128 Command<Commands::BuildRail>::Post(tile, _cur_railtype, track, _settings_client.gui.auto_remove_signals);
129}
130
132static constexpr std::array<DiagDirectionIndexArray<Track>, 3> _place_depot_extra_track{{
133 {Track::Left, Track::Upper, Track::Upper, Track::Right}, // First additional track for directions 0..3
134 {Track::X, Track::Y, Track::X, Track::Y}, // Second additional track
135 {Track::Lower, Track::Left, Track::Right, Track::Lower}, // Third additional track
136}};
137
139static constexpr std::array<DiagDirectionIndexArray<DiagDirection>, 3> _place_depot_extra_dir{{
140 {DiagDirection::SE, DiagDirection::SW, DiagDirection::SE, DiagDirection::SW}, // First additional track for directions 0..3
143}};
144
145void CcRailDepot(Commands, const CommandCost &result, TileIndex tile, RailType, DiagDirection dir)
146{
147 if (result.Failed()) return;
148
149 if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile);
150 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
151
152 tile += TileOffsByDiagDir(dir);
153
154 if (IsTileType(tile, TileType::Railway)) {
156
157 /* Don't place the rail straight out of the depot of there is another depot across from it. */
158 Tile double_depot_tile = tile + TileOffsByDiagDir(dir);
159 bool is_double_depot = IsValidTile(double_depot_tile) && IsRailDepotTile(double_depot_tile);
160 if (!is_double_depot) PlaceExtraDepotRail(tile, _place_depot_extra_dir[1][dir], _place_depot_extra_track[1][dir]);
161
163 }
164}
165
171{
174 return;
175 }
176
177 Axis axis = GetAxisForNewRailWaypoint(tile);
178 if (IsValidAxis(axis)) {
179 /* Valid tile for waypoints */
181 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
182 } else {
183 /* Tile where we can't build rail waypoints. This is always going to fail,
184 * but provides the user with a proper error message. */
185 Command<Commands::BuildRailWaypoint>::Post(STR_ERROR_CAN_T_BUILD_RAIL_WAYPOINT , tile, Axis::X, 1, 1, STAT_CLASS_WAYP, 0, StationID::Invalid(), false);
186 }
187}
188
189void CcStation(Commands, const CommandCost &result, TileIndex tile)
190{
191 if (result.Failed()) return;
192
193 if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile);
194 /* Only close the station builder window if the default station and non persistent building is chosen. */
195 if (_station_gui.sel_class == STAT_CLASS_DFLT && _station_gui.sel_type == 0 && !_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
196}
197
203{
206 VpSetPlaceSizingLimit(-1);
207 } else if (_settings_client.gui.station_dragdrop) {
209 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
210 } else {
211 int w = _settings_client.gui.station_numtracks;
212 int h = _settings_client.gui.station_platlength;
213 if (_station_gui.axis == Axis::X) std::swap(w, h);
214
217 uint8_t numtracks = _settings_client.gui.station_numtracks;
218 uint8_t platlength = _settings_client.gui.station_platlength;
219 bool adjacent = _ctrl_pressed;
220
221 auto proc = [=](bool test, StationID to_join) -> bool {
222 if (test) {
223 return Command<Commands::BuildRailStation>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildRailStation>()), tile, rt, params.axis, numtracks, platlength, params.sel_class, params.sel_type, StationID::Invalid(), adjacent).Succeeded();
224 } else {
225 return Command<Commands::BuildRailStation>::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, tile, rt, params.axis, numtracks, platlength, params.sel_class, params.sel_type, to_join, adjacent);
226 }
227 };
228
229 ShowSelectStationIfNeeded(TileArea(tile, w, h), proc);
230 }
231}
232
239{
241
242 if (trackbits.Any(TRACK_BIT_VERT)) { // N-S direction
243 trackbits = (_tile_fract_coords.x <= _tile_fract_coords.y) ? Track::Right : Track::Left;
244 }
245
246 if (trackbits.Any(TRACK_BIT_HORZ)) { // E-W direction
247 trackbits = (_tile_fract_coords.x + _tile_fract_coords.y <= 15) ? Track::Upper : Track::Lower;
248 }
249
250 Track track = FindFirstTrack(trackbits);
251
253 Command<Commands::RemoveSignal>::Post(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM, CcPlaySound_CONSTRUCTION_RAIL, tile, track);
254 } else {
255 /* Which signals should we cycle through? */
256 bool tile_has_signal = IsPlainRailTile(tile) && IsValidTrack(track) && HasSignalOnTrack(tile, track);
257 SignalType cur_signal_on_tile = tile_has_signal ? GetSignalType(tile, track) : _cur_signal_type;
258 SignalType cycle_start;
259 SignalType cycle_end;
260
261 /* Start with the least restrictive case: the player wants to cycle through all signals they can see. */
262 if (_settings_client.gui.cycle_signal_types == SIGNAL_CYCLE_ALL) {
263 cycle_start = _settings_client.gui.signal_gui_mode == SIGNAL_GUI_ALL ? SignalType::Block : SignalType::Path;
264 cycle_end = SignalType::PathOneWay;
265 } else {
266 /* Only cycle through signals of the same group (block or path) as the current signal on the tile. */
267 if (cur_signal_on_tile <= SignalType::Combo) {
268 /* Block signals only. */
269 cycle_start = SignalType::Block;
270 cycle_end = SignalType::Combo;
271 } else {
272 /* Path signals only. */
273 cycle_start = SignalType::Path;
274 cycle_end = SignalType::PathOneWay;
275 }
276 }
277
278 if (FindWindowById(WindowClass::BuildSignal, 0) != nullptr) {
279 /* signal GUI is used */
280 Command<Commands::BuildSignal>::Post(_convert_signal_button ? STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, CcPlaySound_CONSTRUCTION_RAIL,
281 tile, track, _cur_signal_type, _cur_signal_variant, _convert_signal_button, false, _ctrl_pressed, cycle_start, cycle_end, 0, 0);
282 } else {
284 Command<Commands::BuildSignal>::Post(STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, CcPlaySound_CONSTRUCTION_RAIL,
285 tile, track, _settings_client.gui.default_signal_type, sigvar, false, false, _ctrl_pressed, cycle_start, cycle_end, 0, 0);
286
287 }
288 }
289}
290
296static void PlaceRail_Bridge(TileIndex tile, Window *w)
297{
298 if (IsBridgeTile(tile)) {
299 TileIndex other_tile = GetOtherTunnelBridgeEnd(tile);
300 Point pt = {0, 0};
301 w->OnPlaceMouseUp(VPM_X_OR_Y, DDSP_BUILD_BRIDGE, pt, other_tile, tile);
302 } else {
304 }
305}
306
313{
314 if (result.Succeeded()) {
315 if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile);
316 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
317 } else {
319 }
320}
321
334
341{
342 if (w->IsWidgetDisabled(WID_RAT_REMOVE)) return false;
343
344 /* allow ctrl to switch remove mode only for these widgets */
345 for (WidgetID i = WID_RAT_BUILD_NS; i <= WID_RAT_BUILD_STATION; i++) {
346 if ((i <= WID_RAT_AUTORAIL || i >= WID_RAT_BUILD_WAYPOINT) && w->IsWidgetLowered(i)) {
348 return true;
349 }
350 }
351
352 return false;
353}
354
355
362{
363 if (w->IsWidgetDisabled(WID_RAT_REMOVE)) return;
365 SndClickBeep();
366
367 /* handle station builder */
370 /* starting drag & drop remove */
371 if (!_settings_client.gui.station_dragdrop) {
372 SetTileSelectSize(1, 1);
373 } else {
374 VpSetPlaceSizingLimit(-1);
375 }
376 } else {
377 /* starting station build mode */
378 if (!_settings_client.gui.station_dragdrop) {
379 int x = _settings_client.gui.station_numtracks;
380 int y = _settings_client.gui.station_platlength;
381 if (_station_gui.axis == Axis::X) std::swap(x, y);
382 SetTileSelectSize(x, y);
383 } else {
384 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
385 }
386 }
387 }
388}
389
390static void DoRailroadTrack(Track track)
391{
393 Command<Commands::RemoveRailLong>::Post(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL,
394 TileVirtXY(_thd.selend.x, _thd.selend.y), TileVirtXY(_thd.selstart.x, _thd.selstart.y), track);
395 } else {
396 Command<Commands::BuildRailLong>::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL,
397 TileVirtXY(_thd.selend.x, _thd.selend.y), TileVirtXY(_thd.selstart.x, _thd.selstart.y), _cur_railtype, track, _settings_client.gui.auto_remove_signals, false);
398 }
399}
400
401static void HandleAutodirPlacement()
402{
403 Track trackstat = static_cast<Track>( _thd.drawstyle & HT_DIR_MASK); // 0..5
404
405 if (_thd.drawstyle & HT_RAIL) { // one tile case
406 GenericPlaceRail(TileVirtXY(_thd.selend.x, _thd.selend.y), trackstat);
407 return;
408 }
409
410 DoRailroadTrack(trackstat);
411}
412
420{
421 Track track = static_cast<Track>(_thd.drawstyle & HT_DIR_MASK); // 0..5
422
423 if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT) { // one tile case
424 GenericPlaceSignals(TileVirtXY(_thd.selend.x, _thd.selend.y));
425 return;
426 }
427
428 /* _settings_client.gui.drag_signals_density is given as a parameter such that each user
429 * in a network game can specify their own signal density */
431 Command<Commands::RemoveSignalLong>::Post(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM, CcPlaySound_CONSTRUCTION_RAIL,
432 TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), track, _ctrl_pressed);
433 } else {
434 bool sig_gui = FindWindowById(WindowClass::BuildSignal, 0) != nullptr;
435 SignalType sigtype = sig_gui ? _cur_signal_type : _settings_client.gui.default_signal_type;
437 Command<Commands::BuildSignalLong>::Post(STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, CcPlaySound_CONSTRUCTION_RAIL,
438 TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), track, sigtype, sigvar, false, _ctrl_pressed, !_settings_client.gui.drag_signals_fixed_distance, _settings_client.gui.drag_signals_density);
439 }
440}
441
442
444struct BuildRailToolbarWindow : Window {
447
448 BuildRailToolbarWindow(WindowDesc &desc, RailType railtype) : Window(desc), railtype(railtype)
449 {
450 this->CreateNestedTree();
453 this->OnInvalidateData();
454
455 if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
456 }
457
458 void Close([[maybe_unused]] int data = 0) override
459 {
462 if (_settings_client.gui.link_terraform_toolbar) CloseWindowById(WindowClass::ScenarioGenerateLandscape, 0, false);
463 CloseWindowById(WindowClass::JoinStation, 0);
464 this->Window::Close();
465 }
466
473
474 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
475 {
476 if (!gui_scope) return;
477
478 if (_cur_railtype != this->railtype) {
480
481 /* Update cursor and all sub windows. */
482 if (_thd.GetCallbackWnd() == this) SetCursor(this->GetCursorForWidget(this->last_user_action), PAL_NONE);
483 for (WindowClass cls : {WindowClass::BuildStation, WindowClass::BuildSignal, WindowClass::BuildWaypoint, WindowClass::BuildDepot}) {
485 }
486 }
487
488 if (!ValParamRailType(this->railtype)) {
489 /* Close toolbar if rail type is not available. */
490 this->Close();
491 return;
492 }
493
495 for (const WidgetID widget : can_build_widgets) this->SetWidgetDisabledState(widget, !can_build);
496 if (!can_build) {
497 CloseWindowById(WindowClass::BuildSignal, TransportType::Rail);
498 CloseWindowById(WindowClass::BuildStation, TransportType::Rail);
499 CloseWindowById(WindowClass::BuildDepot, TransportType::Rail);
500 CloseWindowById(WindowClass::BuildWaypoint, TransportType::Rail);
501 CloseWindowById(WindowClass::JoinStation, 0);
502 }
503 }
504
505 bool OnTooltip([[maybe_unused]] Point pt, WidgetID widget, TooltipCloseCondition close_cond) override
506 {
508 if (can_build) return false;
509
510 if (std::ranges::find(can_build_widgets, widget) == std::end(can_build_widgets)) return false;
511
512 GuiShowTooltips(this, GetEncodedString(STR_TOOLBAR_DISABLED_NO_VEHICLE_AVAILABLE), close_cond);
513 return true;
514 }
515
516 void OnInit() override
517 {
518 /* Configure the rail toolbar for the railtype. */
519 const RailTypeInfo *rti = GetRailTypeInfo(this->railtype);
528 }
529
535 {
536 this->railtype = railtype;
537 this->ReInit();
538 }
539
540 void UpdateRemoveWidgetStatus(WidgetID clicked_widget)
541 {
542 switch (clicked_widget) {
543 case WID_RAT_REMOVE:
544 /* If it is the removal button that has been clicked, do nothing,
545 * as it is up to the other buttons to drive removal status */
546 return;
547
548 case WID_RAT_BUILD_NS:
549 case WID_RAT_BUILD_X:
550 case WID_RAT_BUILD_EW:
551 case WID_RAT_BUILD_Y:
552 case WID_RAT_AUTORAIL:
556 /* Removal button is enabled only if the rail/signal/waypoint/station
557 * button is still lowered. Once raised, it has to be disabled */
558 this->SetWidgetDisabledState(WID_RAT_REMOVE, !this->IsWidgetLowered(clicked_widget));
559 break;
560
561 default:
562 /* When any other buttons than rail/signal/waypoint/station, raise and
563 * disable the removal button */
566 break;
567 }
568 }
569
570 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
571 {
572 if (widget == WID_RAT_CAPTION) {
573 const RailTypeInfo *rti = GetRailTypeInfo(this->railtype);
574 if (rti->max_speed > 0) {
575 return GetString(STR_TOOLBAR_RAILTYPE_VELOCITY, rti->strings.toolbar_caption, PackVelocity(rti->max_speed, VehicleType::Train));
576 }
577 return GetString(rti->strings.toolbar_caption);
578 }
579
580 return this->Window::GetWidgetString(widget, stringid);
581 }
582
607
614 {
615 switch (widget) {
616 case WID_RAT_BUILD_NS: return HT_LINE | HT_DIR_VL;
617 case WID_RAT_BUILD_X: return HT_LINE | HT_DIR_X;
618 case WID_RAT_BUILD_EW: return HT_LINE | HT_DIR_HL;
619 case WID_RAT_BUILD_Y: return HT_LINE | HT_DIR_Y;
620 case WID_RAT_AUTORAIL: return HT_RAIL;
621 case WID_RAT_DEMOLISH: return HT_RECT | HT_DIAGONAL;
622 case WID_RAT_BUILD_DEPOT: return HT_RECT;
623 case WID_RAT_BUILD_WAYPOINT: return HT_RECT;
624 case WID_RAT_BUILD_STATION: return HT_RECT;
625 case WID_RAT_BUILD_SIGNALS: return HT_RECT;
626 case WID_RAT_BUILD_BRIDGE: return HT_RECT;
627 case WID_RAT_BUILD_TUNNEL: return HT_SPECIAL;
629 default: NOT_REACHED();
630 }
631 }
632
633
634 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
635 {
636 if (widget < WID_RAT_BUILD_NS) return;
637
639
640 if (widget == WID_RAT_REMOVE) {
643 return;
644 }
645
646 this->last_user_action = widget;
647 bool started = HandlePlacePushButton(this, widget, this->GetCursorForWidget(widget), this->GetHighLightStyleForWidget(widget));
648
649 switch (widget) {
651 if (started) {
652 ShowBuildTrainDepotPicker(this);
653 }
654 break;
655
657 if (started) {
658 ShowBuildWaypointPicker(this);
659 }
660 break;
661
663 if (started) {
664 ShowStationBuilder(this);
665 }
666 break;
667
669 if (started != _ctrl_pressed) {
670 ShowSignalBuilder(this);
671 }
672 break;
673 }
674 }
675
676 this->UpdateRemoveWidgetStatus(widget);
678 }
679
680 EventState OnHotkey(int hotkey) override
681 {
682 if (IsSpecialHotkey(hotkey)) return this->ChangeRailTypeOnHotkey(hotkey);
683 MarkTileDirtyByTile(TileVirtXY(_thd.pos.x, _thd.pos.y)); // redraw tile selection
684 return Window::OnHotkey(hotkey);
685 }
686
687 void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override
688 {
689 switch (this->last_user_action) {
690 case WID_RAT_BUILD_NS:
692 break;
693
694 case WID_RAT_BUILD_X:
696 break;
697
698 case WID_RAT_BUILD_EW:
700 break;
701
702 case WID_RAT_BUILD_Y:
704 break;
705
706 case WID_RAT_AUTORAIL:
708 break;
709
710 case WID_RAT_DEMOLISH:
712 break;
713
715 Command<Commands::BuildRailDepot>::Post(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT, CcRailDepot, tile, _cur_railtype, _build_depot_direction);
716 break;
717
719 PlaceRail_Waypoint(tile);
720 break;
721
723 PlaceRail_Station(tile);
724 break;
725
728 break;
729
731 PlaceRail_Bridge(tile, this);
732 break;
733
735 Command<Commands::BuildTunnel>::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRailTunnel, tile, TransportType::Rail, _cur_railtype, INVALID_ROADTYPE);
736 break;
737
740 break;
741
742 default: NOT_REACHED();
743 }
744 }
745
746 void OnPlaceDrag(ViewportPlaceMethod select_method, [[maybe_unused]] ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt) override
747 {
748 /* no dragging if you have pressed the convert button */
749 if (FindWindowById(WindowClass::BuildSignal, 0) != nullptr && _convert_signal_button && this->IsWidgetLowered(WID_RAT_BUILD_SIGNALS)) return;
750
751 VpSelectTilesWithMethod(pt.x, pt.y, select_method);
752 }
753
754 Point OnInitialPosition(int16_t sm_width, [[maybe_unused]] int16_t sm_height, [[maybe_unused]] int window_number) override
755 {
756 return AlignInitialConstructionToolbar(sm_width);
757 }
758
759 void OnPlaceMouseUp([[maybe_unused]] ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt, TileIndex start_tile, TileIndex end_tile) override
760 {
761 if (pt.x != -1) {
762 switch (select_proc) {
763 default: NOT_REACHED();
765 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
767 break;
768
769 case DDSP_PLACE_RAIL:
770 HandleAutodirPlacement();
771 break;
772
775 break;
776
778 GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
779 break;
780
782 Command<Commands::ConvertRail>::Post(STR_ERROR_CAN_T_CONVERT_RAIL, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _cur_railtype, _ctrl_pressed);
783 break;
784
788 /* Station */
790 bool keep_rail = !_ctrl_pressed;
791 Command<Commands::RemoveFromRailStation>::Post(STR_ERROR_CAN_T_REMOVE_PART_OF_STATION, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, keep_rail);
792 } else {
793 HandleStationPlacement(start_tile, end_tile);
794 }
795 } else {
796 /* Waypoint */
798 bool keep_rail = !_ctrl_pressed;
799 Command<Commands::RemoveFromRailWaypoint>::Post(STR_ERROR_CAN_T_REMOVE_RAIL_WAYPOINT , CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, keep_rail);
800 } else {
801 TileArea ta(start_tile, end_tile);
802 Axis axis = select_method == VPM_X_LIMITED ? Axis::X : Axis::Y;
803 bool adjacent = _ctrl_pressed;
804
805 auto proc = [=](bool test, StationID to_join) -> bool {
806 if (test) {
807 return Command<Commands::BuildRailWaypoint>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildRailWaypoint>()), ta.tile, axis, ta.w, ta.h, _waypoint_gui.sel_class, _waypoint_gui.sel_type, StationID::Invalid(), adjacent).Succeeded();
808 } else {
809 return Command<Commands::BuildRailWaypoint>::Post(STR_ERROR_CAN_T_BUILD_RAIL_WAYPOINT , CcPlaySound_CONSTRUCTION_RAIL, ta.tile, axis, ta.w, ta.h, _waypoint_gui.sel_class, _waypoint_gui.sel_type, to_join, adjacent);
810 }
811 };
812
814 }
815 }
816 break;
817 }
818 }
819 }
820
821 void OnPlaceObjectAbort() override
822 {
825
826 this->RaiseButtons();
829
830 CloseWindowById(WindowClass::BuildSignal, TransportType::Rail);
831 CloseWindowById(WindowClass::BuildStation, TransportType::Rail);
832 CloseWindowById(WindowClass::BuildDepot, TransportType::Rail);
833 CloseWindowById(WindowClass::BuildWaypoint, TransportType::Rail);
834 CloseWindowById(WindowClass::JoinStation, 0);
835 CloseWindowByClass(WindowClass::BuildBridge);
836 }
837
838 void OnPlacePresize([[maybe_unused]] Point pt, TileIndex tile) override
839 {
840 Command<Commands::BuildTunnel>::Do(DoCommandFlag::Auto, tile, TransportType::Rail, _cur_railtype, INVALID_ROADTYPE);
842 }
843
845 {
846 /* do not toggle Remove button by Ctrl when placing station */
849 }
850
851 void OnRealtimeTick([[maybe_unused]] uint delta_ms) override
852 {
853 if (this->IsWidgetLowered(WID_RAT_BUILD_WAYPOINT)) CheckRedrawRailWaypointCoverage(this);
854 }
855
862 {
863 auto [index, step] = GetListIndexStep(SpecialListHotkeys(hotkey), _sorted_railtypes, this->railtype);
864
866 index = (index + step) % _sorted_railtypes.size();
867 }
868
871
872 /* Update cursor and all sub windows. */
873 if (_thd.GetCallbackWnd() == this) SetCursor(this->GetCursorForWidget(this->last_user_action), PAL_NONE);
874 for (WindowClass cls : {WindowClass::BuildStation, WindowClass::BuildSignal, WindowClass::BuildWaypoint, WindowClass::BuildDepot}) {
876 }
877
878 return EventState::Handled;
879 }
880
887 {
888 if (_game_mode != GameMode::Normal) return EventState::NotHandled;
890 if (w == nullptr) return EventState::NotHandled;
891 return w->OnHotkey(hotkey);
892 }
893
894 static inline HotkeyList hotkeys{"railtoolbar", {
895 Hotkey('1', "build_ns", WID_RAT_BUILD_NS),
896 Hotkey('2', "build_x", WID_RAT_BUILD_X),
897 Hotkey('3', "build_ew", WID_RAT_BUILD_EW),
898 Hotkey('4', "build_y", WID_RAT_BUILD_Y),
899 Hotkey({'5', 'A' | WKC_GLOBAL_HOTKEY}, "autorail", WID_RAT_AUTORAIL),
900 Hotkey('6', "demolish", WID_RAT_DEMOLISH),
901 Hotkey('7', "depot", WID_RAT_BUILD_DEPOT),
902 Hotkey('8', "waypoint", WID_RAT_BUILD_WAYPOINT),
903 Hotkey('9', "station", WID_RAT_BUILD_STATION),
904 Hotkey('S', "signal", WID_RAT_BUILD_SIGNALS),
905 Hotkey('B', "bridge", WID_RAT_BUILD_BRIDGE),
906 Hotkey('T', "tunnel", WID_RAT_BUILD_TUNNEL),
907 Hotkey('R', "remove", WID_RAT_REMOVE),
908 Hotkey('C', "convert", WID_RAT_CONVERT_RAIL),
911 Hotkey(WKC_L_BRACKET | WKC_CTRL, "first_railtype", to_underlying(SpecialListHotkeys::FirstItem)),
912 Hotkey(WKC_R_BRACKET | WKC_CTRL, "last_railtype", to_underlying(SpecialListHotkeys::LastItem)),
914};
915
916static constexpr std::initializer_list<NWidgetPart> _nested_build_rail_widgets = {
921 EndContainer(),
924 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_RAIL_NS, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
926 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_RAIL_NE, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
928 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_RAIL_EW, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
930 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_RAIL_NW, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
932 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_AUTORAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL),
933
935
937 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
939 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_DEPOT_RAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING),
941 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_WAYPOINT, STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT),
943 SetFill(0, 1), SetToolbarMinimalSize(2), SetSpriteTip(SPR_IMG_RAIL_STATION, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION),
945 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_RAIL_SIGNALS, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS),
947 SetFill(0, 1), SetToolbarMinimalSize(2), SetSpriteTip(SPR_IMG_BRIDGE, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE),
949 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_TUNNEL_RAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL),
951 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_REMOVE, STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR),
953 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_CONVERT_RAIL, STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL),
954 EndContainer(),
955};
956
959 WindowPosition::Manual, "toolbar_rail", 0, 0,
960 WindowClass::BuildToolbar, WindowClass::None,
962 _nested_build_rail_widgets,
963 &BuildRailToolbarWindow::hotkeys
964);
965
966
976{
977 if (!Company::IsValidID(_local_company)) return nullptr;
978 if (!ValParamRailType(railtype)) return nullptr;
979
980 _cur_railtype = railtype;
981 Window *w = BringWindowToFrontById(WindowClass::BuildToolbar, TransportType::Rail);
982 if (w != nullptr) {
983 w->OnInvalidateData();
984 return w;
985 }
986
987 CloseWindowByClass(WindowClass::BuildToolbar);
989 return new BuildRailToolbarWindow(_build_rail_desc, railtype);
990}
991
992/* TODO: For custom stations, respect their allowed platforms/lengths bitmasks!
993 * --pasky */
994
995static void HandleStationPlacement(TileIndex start, TileIndex end)
996{
997 TileArea ta(start, end);
998 uint numtracks = ta.w;
999 uint platlength = ta.h;
1000
1001 if (_station_gui.axis == Axis::X) std::swap(numtracks, platlength);
1002
1005 bool adjacent = _ctrl_pressed;
1006
1007 auto proc = [=](bool test, StationID to_join) -> bool {
1008 if (test) {
1009 return Command<Commands::BuildRailStation>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildRailStation>()), ta.tile, rt, params.axis, numtracks, platlength, params.sel_class, params.sel_type, StationID::Invalid(), adjacent).Succeeded();
1010 } else {
1011 return Command<Commands::BuildRailStation>::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, ta.tile, rt, params.axis, numtracks, platlength, params.sel_class, params.sel_type, to_join, adjacent);
1012 }
1013 };
1014
1015 ShowSelectStationIfNeeded(ta, proc);
1016}
1017
1024{
1025 for (TileIndex t : bst->train_station) {
1026 if (bst->TileBelongsToRailStation(t) && HasStationRail(t) && GetCustomStationSpecIndex(t) == 0) return true;
1027 }
1028 return false;
1029}
1030
1031class StationPickerCallbacks : public PickerCallbacksNewGRFClass<StationClass> {
1032public:
1033 StationPickerCallbacks() : PickerCallbacksNewGRFClass<StationClass>("fav_stations") {}
1034
1036
1037 StringID GetClassTooltip() const override { return STR_PICKER_STATION_CLASS_TOOLTIP; }
1038 StringID GetTypeTooltip() const override { return STR_PICKER_STATION_TYPE_TOOLTIP; }
1039 StringID GetCollectionTooltip() const override { return STR_PICKER_STATION_COLLECTION_TOOLTIP; }
1040
1041 bool IsActive() const override
1042 {
1043 for (const auto &cls : StationClass::Classes()) {
1044 if (IsWaypointClass(cls)) continue;
1045 for (const auto *spec : cls.Specs()) {
1046 if (spec != nullptr) return true;
1047 }
1048 }
1049 return false;
1050 }
1051
1052 bool HasClassChoice() const override
1053 {
1054 return std::ranges::count_if(StationClass::Classes(), [](const auto &cls) { return !IsWaypointClass(cls); }) > 1;
1055 }
1056
1057 int GetSelectedClass() const override { return _station_gui.sel_class.base(); }
1058 void SetSelectedClass(int id) const override { _station_gui.sel_class = this->GetClassIndex(id); }
1059
1060 StringID GetClassName(int id) const override
1061 {
1062 const auto *sc = GetClass(id);
1063 if (IsWaypointClass(*sc)) return INVALID_STRING_ID;
1064 return sc->name;
1065 }
1066
1067 int GetSelectedType() const override { return _station_gui.sel_type; }
1068 void SetSelectedType(int id) const override { _station_gui.sel_type = id; }
1069
1070 StringID GetTypeName(int cls_id, int id) const override
1071 {
1072 const auto *spec = this->GetSpec(cls_id, id);
1073 return (spec == nullptr) ? STR_STATION_CLASS_DFLT_STATION : spec->name;
1074 }
1075
1076 std::span<const BadgeID> GetTypeBadges(int cls_id, int id) const override
1077 {
1078 const auto *spec = this->GetSpec(cls_id, id);
1079 if (spec == nullptr) return {};
1080 return spec->badges;
1081 }
1082
1083 bool IsTypeAvailable(int cls_id, int id) const override
1084 {
1085 return IsStationAvailable(this->GetSpec(cls_id, id));
1086 }
1087
1088 void DrawType(int x, int y, int cls_id, int id) const override
1089 {
1090 if (!DrawStationTile(x, y, _cur_railtype, _station_gui.axis, this->GetClassIndex(cls_id), id)) {
1091 StationPickerDrawSprite(x, y, StationType::Rail, _cur_railtype, INVALID_ROADTYPE, 2 + to_underlying(_station_gui.axis));
1092 }
1093 }
1094
1095 void FillUsedItems(std::set<PickerItem> &items) override
1096 {
1097 bool default_added = false;
1098 for (const Station *st : Station::Iterate()) {
1099 if (st->owner != _local_company) continue;
1100 if (!default_added && StationUsesDefaultType(st)) {
1101 items.insert({GrfID{}, 0, STAT_CLASS_DFLT.base(), 0});
1102 default_added = true;
1103 }
1104 for (const auto &sm : st->speclist) {
1105 if (sm.spec == nullptr) continue;
1106 items.insert({sm.grfid, sm.localidx, sm.spec->class_index.base(), sm.spec->index});
1107 }
1108 }
1109 }
1110
1111 static StationPickerCallbacks instance;
1112};
1113/* static */ StationPickerCallbacks StationPickerCallbacks::instance;
1114
1115struct BuildRailStationWindow : public PickerWindow {
1116private:
1118
1124 void CheckSelectedSize(const StationSpec *statspec)
1125 {
1126 if (statspec == nullptr || _settings_client.gui.station_dragdrop) return;
1127
1128 /* If current number of tracks is not allowed, make it as big as possible */
1129 if (HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
1130 this->RaiseWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN);
1131 _settings_client.gui.station_numtracks = 1;
1132 if (statspec->disallowed_platforms != UINT8_MAX) {
1133 while (HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
1134 _settings_client.gui.station_numtracks++;
1135 }
1136 this->LowerWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN);
1137 }
1138 }
1139
1140 if (HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
1141 this->RaiseWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
1142 _settings_client.gui.station_platlength = 1;
1143 if (statspec->disallowed_lengths != UINT8_MAX) {
1144 while (HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
1145 _settings_client.gui.station_platlength++;
1146 }
1147 this->LowerWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
1148 }
1149 }
1150 }
1151
1156 {
1157 if (_settings_client.gui.station_dragdrop) {
1158 SetTileSelectSize(1, 1);
1159 } else {
1160 int x = _settings_client.gui.station_numtracks;
1161 int y = _settings_client.gui.station_platlength;
1162 if (_station_gui.axis == Axis::X) std::swap(x, y);
1164 SetTileSelectSize(x, y);
1165 }
1166 }
1167
1168 int rad = (_settings_game.station.modified_catchment) ? CA_TRAIN : CA_UNMODIFIED;
1169 if (_settings_client.gui.station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
1170 }
1171
1172public:
1174 {
1175 this->coverage_height = 2 * GetCharacterHeight(FontSize::Normal) + WidgetDimensions::scaled.vsep_normal;
1176 this->ConstructWindow();
1177 }
1178
1179 void OnInit() override
1180 {
1182 if (_settings_client.gui.station_dragdrop) {
1184 } else {
1185 this->LowerWidget(WID_BRAS_PLATFORM_NUM_BEGIN + _settings_client.gui.station_numtracks);
1186 this->LowerWidget(WID_BRAS_PLATFORM_LEN_BEGIN + _settings_client.gui.station_platlength);
1187 }
1188 this->SetWidgetLoweredState(WID_BRAS_HIGHLIGHT_OFF, !_settings_client.gui.station_show_coverage);
1189 this->SetWidgetLoweredState(WID_BRAS_HIGHLIGHT_ON, _settings_client.gui.station_show_coverage);
1190 this->SetSelectedSize();
1191
1192 this->PickerWindow::OnInit();
1193 }
1194
1195 void Close([[maybe_unused]] int data = 0) override
1196 {
1197 CloseWindowById(WindowClass::JoinStation, 0);
1198 this->PickerWindow::Close();
1199 }
1200
1201 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
1202 {
1203 if (gui_scope) {
1204 const StationSpec *statspec = StationClass::Get(_station_gui.sel_class)->GetSpec(_station_gui.sel_type);
1205 this->CheckSelectedSize(statspec);
1206 }
1207
1208 this->PickerWindow::OnInvalidateData(data, gui_scope);
1209 }
1210
1211 void OnPaint() override
1212 {
1213 const StationSpec *statspec = StationClass::Get(_station_gui.sel_class)->GetSpec(_station_gui.sel_type);
1214 int rad = (_settings_game.station.modified_catchment) ? CA_TRAIN : CA_UNMODIFIED;
1215
1216 for (uint bits = 0; bits < 7; bits++) {
1217 bool disable = bits >= _settings_game.station.station_spread;
1218 if (statspec == nullptr) {
1219 this->SetWidgetDisabledState(bits + WID_BRAS_PLATFORM_NUM_1, disable);
1220 this->SetWidgetDisabledState(bits + WID_BRAS_PLATFORM_LEN_1, disable);
1221 } else {
1222 this->SetWidgetDisabledState(bits + WID_BRAS_PLATFORM_NUM_1, HasBit(statspec->disallowed_platforms, bits) || disable);
1223 this->SetWidgetDisabledState(bits + WID_BRAS_PLATFORM_LEN_1, HasBit(statspec->disallowed_lengths, bits) || disable);
1224 }
1225 }
1226
1227 this->DrawWidgets();
1228
1229 if (this->IsShaded()) return;
1230 /* 'Accepts' and 'Supplies' texts. */
1231 Rect r = this->GetWidget<NWidgetBase>(WID_BRAS_COVERAGE_TEXTS)->GetCurrentRect();
1232 const int bottom = r.bottom;
1233 r.bottom = INT_MAX; // Allow overflow as we want to know the required height.
1234 if (statspec != nullptr) r.top = DrawBadgeNameList(r, statspec->badges, GrfSpecFeature::Stations);
1235 r.top = DrawStationCoverageAreaText(r, SCT_ALL, rad, false) + WidgetDimensions::scaled.vsep_normal;
1236 r.top = DrawStationCoverageAreaText(r, SCT_ALL, rad, true);
1237 /* Resize background if the window is too small.
1238 * Never make the window smaller to avoid oscillating if the size change affects the acceptance.
1239 * (This is the case, if making the window bigger moves the mouse into the window.) */
1240 if (r.top > bottom) {
1241 this->coverage_height += r.top - bottom;
1242 this->ReInit();
1243 }
1244 }
1245
1246 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
1247 {
1248 switch (widget) {
1251 size.width = ScaleGUITrad(PREVIEW_WIDTH) + WidgetDimensions::scaled.fullbevel.Horizontal();
1252 size.height = ScaleGUITrad(PREVIEW_HEIGHT) + WidgetDimensions::scaled.fullbevel.Vertical();
1253 break;
1254
1256 size.height = this->coverage_height;
1257 break;
1258
1259 default:
1260 this->PickerWindow::UpdateWidgetSize(widget, size, padding, fill, resize);
1261 break;
1262 }
1263 }
1264
1265 void DrawWidget(const Rect &r, WidgetID widget) const override
1266 {
1267 DrawPixelInfo tmp_dpi;
1268
1269 switch (widget) {
1271 /* Set up a clipping area for the '/' station preview */
1272 Rect ir = r.Shrink(WidgetDimensions::scaled.bevel);
1273 if (FillDrawPixelInfo(&tmp_dpi, ir)) {
1274 AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
1277 if (!DrawStationTile(x, y, _cur_railtype, Axis::X, _station_gui.sel_class, _station_gui.sel_type)) {
1278 StationPickerDrawSprite(x, y, StationType::Rail, _cur_railtype, INVALID_ROADTYPE, 2);
1279 }
1280 }
1281 break;
1282 }
1283
1285 /* Set up a clipping area for the '\' station preview */
1286 Rect ir = r.Shrink(WidgetDimensions::scaled.bevel);
1287 if (FillDrawPixelInfo(&tmp_dpi, ir)) {
1288 AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
1291 if (!DrawStationTile(x, y, _cur_railtype, Axis::Y, _station_gui.sel_class, _station_gui.sel_type)) {
1292 StationPickerDrawSprite(x, y, StationType::Rail, _cur_railtype, INVALID_ROADTYPE, 3);
1293 }
1294 }
1295 break;
1296 }
1297
1298 default:
1299 this->PickerWindow::DrawWidget(r, widget);
1300 break;
1301 }
1302 }
1303
1304 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1305 {
1306 switch (widget) {
1310 _station_gui.axis = static_cast<Axis>(widget - WID_BRAS_PLATFORM_DIR_X);
1312
1313 this->SetSelectedSize();
1314 SndClickBeep();
1315 this->SetDirty();
1316 CloseWindowById(WindowClass::JoinStation, 0);
1317 break;
1318
1326 this->RaiseWidget(WID_BRAS_PLATFORM_NUM_BEGIN + _settings_client.gui.station_numtracks);
1328
1329 _settings_client.gui.station_numtracks = widget - WID_BRAS_PLATFORM_NUM_BEGIN;
1330 _settings_client.gui.station_dragdrop = false;
1331
1332 const StationSpec *statspec = StationClass::Get(_station_gui.sel_class)->GetSpec(_station_gui.sel_type);
1333 if (statspec != nullptr && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
1334 /* The previously selected number of platforms in invalid */
1335 for (uint i = 0; i < 7; i++) {
1336 if (!HasBit(statspec->disallowed_lengths, i)) {
1337 this->RaiseWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
1338 _settings_client.gui.station_platlength = i + 1;
1339 break;
1340 }
1341 }
1342 }
1343
1344 this->LowerWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN);
1345 this->LowerWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
1346 this->SetSelectedSize();
1347 SndClickBeep();
1348 this->SetDirty();
1349 CloseWindowById(WindowClass::JoinStation, 0);
1350 break;
1351 }
1352
1360 this->RaiseWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
1362
1363 _settings_client.gui.station_platlength = widget - WID_BRAS_PLATFORM_LEN_BEGIN;
1364 _settings_client.gui.station_dragdrop = false;
1365
1366 const StationSpec *statspec = StationClass::Get(_station_gui.sel_class)->GetSpec(_station_gui.sel_type);
1367 if (statspec != nullptr && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
1368 /* The previously selected number of tracks in invalid */
1369 for (uint i = 0; i < 7; i++) {
1370 if (!HasBit(statspec->disallowed_platforms, i)) {
1371 this->RaiseWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN);
1372 _settings_client.gui.station_numtracks = i + 1;
1373 break;
1374 }
1375 }
1376 }
1377
1378 this->LowerWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN);
1379 this->LowerWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
1380 this->SetSelectedSize();
1381 SndClickBeep();
1382 this->SetDirty();
1383 CloseWindowById(WindowClass::JoinStation, 0);
1384 break;
1385 }
1386
1388 _settings_client.gui.station_dragdrop ^= true;
1389
1391
1392 /* get the first allowed length/number of platforms */
1393 const StationSpec *statspec = StationClass::Get(_station_gui.sel_class)->GetSpec(_station_gui.sel_type);
1394 if (statspec != nullptr && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
1395 for (uint i = 0; i < 7; i++) {
1396 if (!HasBit(statspec->disallowed_lengths, i)) {
1397 this->RaiseWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
1398 _settings_client.gui.station_platlength = i + 1;
1399 break;
1400 }
1401 }
1402 }
1403 if (statspec != nullptr && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
1404 for (uint i = 0; i < 7; i++) {
1405 if (!HasBit(statspec->disallowed_platforms, i)) {
1406 this->RaiseWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN);
1407 _settings_client.gui.station_numtracks = i + 1;
1408 break;
1409 }
1410 }
1411 }
1412
1413 this->SetWidgetLoweredState(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN, !_settings_client.gui.station_dragdrop);
1414 this->SetWidgetLoweredState(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN, !_settings_client.gui.station_dragdrop);
1415 this->SetSelectedSize();
1416 SndClickBeep();
1417 this->SetDirty();
1418 CloseWindowById(WindowClass::JoinStation, 0);
1419 break;
1420 }
1421
1424 _settings_client.gui.station_show_coverage = (widget != WID_BRAS_HIGHLIGHT_OFF);
1425
1426 this->SetWidgetLoweredState(WID_BRAS_HIGHLIGHT_OFF, !_settings_client.gui.station_show_coverage);
1427 this->SetWidgetLoweredState(WID_BRAS_HIGHLIGHT_ON, _settings_client.gui.station_show_coverage);
1428 this->SetSelectedSize();
1429 SndClickBeep();
1430 this->SetDirty();
1431 SetViewportCatchmentStation(nullptr, true);
1432 break;
1433
1434 default:
1435 this->PickerWindow::OnClick(pt, widget, click_count);
1436 break;
1437 }
1438 }
1439
1440 void OnRealtimeTick([[maybe_unused]] uint delta_ms) override
1441 {
1443 }
1444
1451 {
1452 if (_game_mode == GameMode::Menu) return EventState::NotHandled;
1453 Window *w = ShowStationBuilder(FindWindowById(WindowClass::BuildToolbar, TransportType::Rail));
1454 if (w == nullptr) return EventState::NotHandled;
1455 return w->OnHotkey(hotkey);
1456 }
1457
1458 static inline HotkeyList hotkeys{"buildrailstation", {
1459 Hotkey('F', "focus_filter_box", PCWHK_FOCUS_FILTER_BOX),
1461};
1462
1463static constexpr std::initializer_list<NWidgetPart> _nested_station_builder_widgets = {
1466 NWidget(WWT_CAPTION, Colours::DarkGreen), SetStringTip(STR_STATION_BUILD_RAIL_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1469 EndContainer(),
1475 NWidget(WWT_LABEL, Colours::Invalid), SetMinimalSize(144, 11), SetFill(1, 0), SetStringTip(STR_STATION_BUILD_ORIENTATION),
1477 NWidget(WWT_PANEL, Colours::Grey, WID_BRAS_PLATFORM_DIR_X), SetFill(0, 0), SetToolTip(STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(),
1478 NWidget(WWT_PANEL, Colours::Grey, WID_BRAS_PLATFORM_DIR_Y), SetFill(0, 0), SetToolTip(STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(),
1479 EndContainer(),
1480 NWidget(WWT_LABEL, Colours::Invalid), SetMinimalSize(144, 11), SetFill(1, 0), SetStringTip(STR_STATION_BUILD_NUMBER_OF_TRACKS),
1482 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_PLATFORM_NUM_1), SetAspect(1.25f), SetStringTip(STR_BLACK_1, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
1483 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_PLATFORM_NUM_2), SetAspect(1.25f), SetStringTip(STR_BLACK_2, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
1484 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_PLATFORM_NUM_3), SetAspect(1.25f), SetStringTip(STR_BLACK_3, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
1485 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_PLATFORM_NUM_4), SetAspect(1.25f), SetStringTip(STR_BLACK_4, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
1486 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_PLATFORM_NUM_5), SetAspect(1.25f), SetStringTip(STR_BLACK_5, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
1487 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_PLATFORM_NUM_6), SetAspect(1.25f), SetStringTip(STR_BLACK_6, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
1488 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_PLATFORM_NUM_7), SetAspect(1.25f), SetStringTip(STR_BLACK_7, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
1489 EndContainer(),
1490 NWidget(WWT_LABEL, Colours::Invalid), SetMinimalSize(144, 11), SetFill(1, 0), SetStringTip(STR_STATION_BUILD_PLATFORM_LENGTH),
1492 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_PLATFORM_LEN_1), SetAspect(1.25f), SetStringTip(STR_BLACK_1, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
1493 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_PLATFORM_LEN_2), SetAspect(1.25f), SetStringTip(STR_BLACK_2, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
1494 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_PLATFORM_LEN_3), SetAspect(1.25f), SetStringTip(STR_BLACK_3, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
1495 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_PLATFORM_LEN_4), SetAspect(1.25f), SetStringTip(STR_BLACK_4, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
1496 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_PLATFORM_LEN_5), SetAspect(1.25f), SetStringTip(STR_BLACK_5, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
1497 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_PLATFORM_LEN_6), SetAspect(1.25f), SetStringTip(STR_BLACK_6, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
1498 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_PLATFORM_LEN_7), SetAspect(1.25f), SetStringTip(STR_BLACK_7, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
1499 EndContainer(),
1501 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_PLATFORM_DRAG_N_DROP), SetMinimalSize(75, 12), SetStringTip(STR_STATION_BUILD_DRAG_DROP, STR_STATION_BUILD_DRAG_DROP_TOOLTIP),
1502 EndContainer(),
1503 NWidget(WWT_LABEL, Colours::Invalid), SetStringTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE), SetFill(1, 0),
1505 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_HIGHLIGHT_OFF), SetMinimalSize(60, 12), SetStringTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
1506 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAS_HIGHLIGHT_ON), SetMinimalSize(60, 12), SetStringTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
1507 EndContainer(),
1509 EndContainer(),
1510 EndContainer(),
1511 EndContainer(),
1513 EndContainer(),
1514};
1515
1518 WindowPosition::Automatic, "build_station_rail", 0, 0,
1519 WindowClass::BuildStation, WindowClass::BuildToolbar,
1521 _nested_station_builder_widgets,
1522 &BuildRailStationWindow::hotkeys
1523);
1524
1531{
1533}
1534
1535struct BuildSignalWindow : public PickerWindowBase {
1536private:
1539
1545 void DrawSignalSprite(const Rect &r, SpriteID image) const
1546 {
1547 Point offset;
1548 Dimension sprite_size = GetSpriteSize(image, &offset);
1549 Rect ir = r.Shrink(WidgetDimensions::scaled.imgbtn);
1550 int x = CentreBounds(ir.left, ir.right, sprite_size.width - offset.x) - offset.x; // centered
1551 int y = ir.top - sig_sprite_bottom_offset +
1552 (ir.Height() + sig_sprite_size.height) / 2; // aligned to bottom
1553
1554 DrawSprite(image, PAL_NONE, x, y);
1555 }
1556
1559 {
1560 bool show_non_path_signals = (_settings_client.gui.signal_gui_mode == SIGNAL_GUI_ALL);
1561
1562 this->GetWidget<NWidgetStacked>(WID_BS_BLOCK_SEL)->SetDisplayedPlane(show_non_path_signals ? 0 : SZSP_NONE);
1563 this->GetWidget<NWidgetStacked>(WID_BS_BLOCK_SPACER_SEL)->SetDisplayedPlane(show_non_path_signals ? 0 : SZSP_NONE);
1564 }
1565
1566public:
1568 {
1569 this->CreateNestedTree();
1570 this->SetSignalUIMode();
1572 this->OnInvalidateData();
1573 }
1574
1575 void Close([[maybe_unused]] int data = 0) override
1576 {
1577 _convert_signal_button = false;
1579 }
1580
1581 void OnInit() override
1582 {
1583 /* Calculate maximum signal sprite size. */
1584 this->sig_sprite_size.width = 0;
1585 this->sig_sprite_size.height = 0;
1586 this->sig_sprite_bottom_offset = 0;
1588 for (SignalType type : EnumRange(SignalType::End)) {
1591 Point offset;
1592 Dimension sprite_size = GetSpriteSize(rti->gui_sprites.signals[type][variant][state], &offset);
1593 this->sig_sprite_bottom_offset = std::max<int>(this->sig_sprite_bottom_offset, sprite_size.height);
1594 this->sig_sprite_size.width = std::max<int>(this->sig_sprite_size.width, sprite_size.width - offset.x);
1595 this->sig_sprite_size.height = std::max<int>(this->sig_sprite_size.height, sprite_size.height - offset.y);
1596 }
1597 }
1598 }
1599 }
1600
1601 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
1602 {
1603 if (widget == WID_BS_DRAG_SIGNALS_DENSITY_LABEL) {
1604 /* Two digits for signals density. */
1605 size.width = std::max(size.width, 2 * GetDigitWidth() + padding.width + WidgetDimensions::scaled.framerect.Horizontal());
1607 size.width = std::max(size.width, this->sig_sprite_size.width + padding.width);
1608 size.height = std::max(size.height, this->sig_sprite_size.height + padding.height);
1609 }
1610 }
1611
1612 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
1613 {
1614 switch (widget) {
1616 return GetString(STR_JUST_INT, _settings_client.gui.drag_signals_density);
1617
1618 default:
1619 return this->Window::GetWidgetString(widget, stringid);
1620 }
1621 }
1622
1623 void DrawWidget(const Rect &r, WidgetID widget) const override
1624 {
1626 /* Extract signal from widget number. */
1627 SignalType type = static_cast<SignalType>((widget - WID_BS_SEMAPHORE_NORM) % to_underlying(SignalType::End));
1628 SignalVariant var = static_cast<SignalVariant>(to_underlying(SignalVariant::Semaphore) - (widget - WID_BS_SEMAPHORE_NORM) / to_underlying(SignalType::End)); // SignalVariant order is reversed compared to the widgets.
1629 SpriteID sprite = GetRailTypeInfo(_cur_railtype)->gui_sprites.signals[type][var][static_cast<SignalState>(this->IsWidgetLowered(widget))];
1630
1631 this->DrawSignalSprite(r, sprite);
1632 }
1633 }
1634
1635 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1636 {
1637 switch (widget) {
1651
1654
1655 /* Update default (last-used) signal type in config file. */
1656 _settings_client.gui.default_signal_type = _cur_signal_type;
1657
1658 /* If 'remove' button of rail build toolbar is active, disable it. */
1660 Window *w = FindWindowById(WindowClass::BuildToolbar, TransportType::Rail);
1661 if (w != nullptr) ToggleRailButton_Remove(w);
1662 }
1663
1664 SndClickBeep();
1665 break;
1666
1667 case WID_BS_CONVERT:
1669 SndClickBeep();
1670 break;
1671
1673 if (_settings_client.gui.drag_signals_density > 1) {
1674 _settings_client.gui.drag_signals_density--;
1675 }
1676 break;
1677
1679 if (_settings_client.gui.drag_signals_density < 20) {
1680 _settings_client.gui.drag_signals_density++;
1681 }
1682 break;
1683
1684 default: break;
1685 }
1686
1687 this->InvalidateData();
1688 }
1689
1695 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
1696 {
1697 if (!gui_scope) return;
1699
1701
1704 }
1705};
1706
1708static constexpr std::initializer_list<NWidgetPart> _nested_signal_builder_widgets = {
1709 /* Title bar and buttons. */
1712 NWidget(WWT_CAPTION, Colours::DarkGreen, WID_BS_CAPTION), SetStringTip(STR_BUILD_SIGNAL_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1713 EndContainer(),
1714
1715 /* Container for both signal groups, spacers, and convert/autofill buttons. */
1717 /* Block signals (can be hidden). */
1720 /* Semaphore block signals. */
1723 NWidget(WWT_PANEL, Colours::DarkGreen, WID_BS_SEMAPHORE_ENTRY), SetToolTip(STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP), SetToolbarMinimalSize(1), EndContainer(),
1725 NWidget(WWT_PANEL, Colours::DarkGreen, WID_BS_SEMAPHORE_COMBO), SetToolTip(STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP), SetToolbarMinimalSize(1), EndContainer(),
1726 EndContainer(),
1727 /* Electric block signals. */
1733 EndContainer(),
1734 EndContainer(),
1735 EndContainer(),
1736
1737 /* Divider (only shown if block signals visible). */
1740 EndContainer(),
1741
1742 /* Path signals. */
1744 /* Semaphore path signals. */
1747 NWidget(WWT_PANEL, Colours::DarkGreen, WID_BS_SEMAPHORE_PBS_OWAY), SetToolTip(STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP), SetToolbarMinimalSize(1), EndContainer(),
1748 EndContainer(),
1749 /* Electric path signals. */
1752 NWidget(WWT_PANEL, Colours::DarkGreen, WID_BS_ELECTRIC_PBS_OWAY), SetToolTip(STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP), SetToolbarMinimalSize(1), EndContainer(),
1753 EndContainer(),
1754 EndContainer(),
1755
1756 /* Convert/autofill buttons. */
1759 NWidget(WWT_PANEL, Colours::DarkGreen), SetToolTip(STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(0, 1),
1765 EndContainer(),
1766 EndContainer(),
1767 EndContainer(),
1768 EndContainer(),
1769 EndContainer(),
1770};
1771
1774 WindowPosition::Automatic, {}, 0, 0,
1775 WindowClass::BuildSignal, WindowClass::BuildToolbar,
1778);
1779
1784static void ShowSignalBuilder(Window *parent)
1785{
1787}
1788
1789struct BuildRailDepotWindow : public PickerWindowBase {
1790 BuildRailDepotWindow(WindowDesc &desc, Window *parent) : PickerWindowBase(desc, parent)
1791 {
1794 }
1795
1796 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
1797 {
1798 if (!IsInsideMM(widget, WID_BRAD_DEPOT_NE, WID_BRAD_DEPOT_NW + 1)) return;
1799
1800 size.width = ScaleGUITrad(64) + WidgetDimensions::scaled.fullbevel.Horizontal();
1801 size.height = ScaleGUITrad(48) + WidgetDimensions::scaled.fullbevel.Vertical();
1802 }
1803
1804 void DrawWidget(const Rect &r, WidgetID widget) const override
1805 {
1806 if (!IsInsideMM(widget, WID_BRAD_DEPOT_NE, WID_BRAD_DEPOT_NW + 1)) return;
1807
1808 DrawPixelInfo tmp_dpi;
1809 Rect ir = r.Shrink(WidgetDimensions::scaled.bevel);
1810 if (FillDrawPixelInfo(&tmp_dpi, ir)) {
1811 AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
1812 int x = (ir.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31);
1813 int y = (ir.Height() + ScaleSpriteTrad(48)) / 2 - ScaleSpriteTrad(31);
1815 }
1816 }
1817
1818 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1819 {
1820 switch (widget) {
1821 case WID_BRAD_DEPOT_NE:
1822 case WID_BRAD_DEPOT_SE:
1823 case WID_BRAD_DEPOT_SW:
1824 case WID_BRAD_DEPOT_NW:
1828 SndClickBeep();
1829 this->SetDirty();
1830 break;
1831 }
1832 }
1833};
1834
1836static constexpr std::initializer_list<NWidgetPart> _nested_build_depot_widgets = {
1839 NWidget(WWT_CAPTION, Colours::DarkGreen), SetStringTip(STR_BUILD_DEPOT_TRAIN_ORIENTATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1840 EndContainer(),
1844 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAD_DEPOT_NW), SetToolTip(STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
1845 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAD_DEPOT_SW), SetToolTip(STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
1846 EndContainer(),
1848 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAD_DEPOT_NE), SetToolTip(STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
1849 NWidget(WWT_TEXTBTN, Colours::Grey, WID_BRAD_DEPOT_SE), SetToolTip(STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
1850 EndContainer(),
1851 EndContainer(),
1852 EndContainer(),
1853};
1854
1857 WindowPosition::Automatic, {}, 0, 0,
1858 WindowClass::BuildDepot, WindowClass::BuildToolbar,
1861);
1862
1863static void ShowBuildTrainDepotPicker(Window *parent)
1864{
1866}
1867
1868class WaypointPickerCallbacks : public PickerCallbacksNewGRFClass<StationClass> {
1869public:
1870 WaypointPickerCallbacks() : PickerCallbacksNewGRFClass<StationClass>("fav_waypoints") {}
1871
1873
1874 StringID GetClassTooltip() const override { return STR_PICKER_WAYPOINT_CLASS_TOOLTIP; }
1875 StringID GetTypeTooltip() const override { return STR_PICKER_WAYPOINT_TYPE_TOOLTIP; }
1876 StringID GetCollectionTooltip() const override { return STR_PICKER_WAYPOINT_COLLECTION_TOOLTIP; }
1877
1878 bool IsActive() const override
1879 {
1880 for (const auto &cls : StationClass::Classes()) {
1881 if (!IsWaypointClass(cls)) continue;
1882 for (const auto *spec : cls.Specs()) {
1883 if (spec != nullptr) return true;
1884 }
1885 }
1886 return false;
1887 }
1888
1889 bool HasClassChoice() const override
1890 {
1891 return std::ranges::count_if(StationClass::Classes(), [](const auto &cls) { return IsWaypointClass(cls); }) > 1;
1892 }
1893
1894 void Close(int) override { ResetObjectToPlace(); }
1895 int GetSelectedClass() const override { return _waypoint_gui.sel_class.base(); }
1896 void SetSelectedClass(int id) const override { _waypoint_gui.sel_class = this->GetClassIndex(id); }
1897
1898 StringID GetClassName(int id) const override
1899 {
1900 const auto *sc = GetClass(id);
1901 if (!IsWaypointClass(*sc)) return INVALID_STRING_ID;
1902 return sc->name;
1903 }
1904
1905 int GetSelectedType() const override { return _waypoint_gui.sel_type; }
1906 void SetSelectedType(int id) const override { _waypoint_gui.sel_type = id; }
1907
1908 StringID GetTypeName(int cls_id, int id) const override
1909 {
1910 const auto *spec = this->GetSpec(cls_id, id);
1911 return (spec == nullptr) ? STR_STATION_CLASS_WAYP_WAYPOINT : spec->name;
1912 }
1913
1914 std::span<const BadgeID> GetTypeBadges(int cls_id, int id) const override
1915 {
1916 const auto *spec = this->GetSpec(cls_id, id);
1917 if (spec == nullptr) return {};
1918 return spec->badges;
1919 }
1920
1921 bool IsTypeAvailable(int cls_id, int id) const override
1922 {
1923 return IsStationAvailable(this->GetSpec(cls_id, id));
1924 }
1925
1926 void DrawType(int x, int y, int cls_id, int id) const override
1927 {
1928 DrawWaypointSprite(x, y, this->GetClassIndex(cls_id), id, _cur_railtype);
1929 }
1930
1931 void FillUsedItems(std::set<PickerItem> &items) override
1932 {
1933 bool default_added = false;
1934 for (const Waypoint *wp : Waypoint::Iterate()) {
1935 if (wp->owner != _local_company || HasBit(wp->waypoint_flags, WPF_ROAD)) continue;
1936 if (!default_added && StationUsesDefaultType(wp)) {
1937 items.insert({GrfID{}, 0, STAT_CLASS_WAYP.base(), 0});
1938 default_added = true;
1939 }
1940 for (const auto &sm : wp->speclist) {
1941 if (sm.spec == nullptr) continue;
1942 items.insert({sm.grfid, sm.localidx, sm.spec->class_index.base(), sm.spec->index});
1943 }
1944 }
1945 }
1946
1947 static WaypointPickerCallbacks instance;
1948};
1949/* static */ WaypointPickerCallbacks WaypointPickerCallbacks::instance;
1950
1951struct BuildRailWaypointWindow : public PickerWindow {
1952 BuildRailWaypointWindow(WindowDesc &desc, Window *parent) : PickerWindow(desc, parent, TransportType::Rail, WaypointPickerCallbacks::instance)
1953 {
1954 this->ConstructWindow();
1955 }
1956
1957 static inline HotkeyList hotkeys{"buildrailwaypoint", {
1958 Hotkey('F', "focus_filter_box", PCWHK_FOCUS_FILTER_BOX),
1959 }};
1960};
1961
1975
1978 WindowPosition::Automatic, "build_waypoint", 0, 0,
1979 WindowClass::BuildWaypoint, WindowClass::BuildToolbar,
1982 &BuildRailWaypointWindow::hotkeys
1983);
1984
1985static void ShowBuildWaypointPicker(Window *parent)
1986{
1987 if (!WaypointPickerCallbacks::instance.IsActive()) return;
1989}
1990
1995{
1997 _station_gui.sel_class = STAT_CLASS_DFLT;
1998 _station_gui.sel_type = 0;
1999 _waypoint_gui.sel_class = STAT_CLASS_WAYP;
2000 _waypoint_gui.sel_type = 0;
2001}
2002
2008{
2009 if (disable && _last_built_railtype == RAILTYPE_ELECTRIC) {
2011 BuildRailToolbarWindow *w = dynamic_cast<BuildRailToolbarWindow *>(FindWindowById(WindowClass::BuildToolbar, TransportType::Rail));
2012 if (w != nullptr) w->ModifyRailType(_cur_railtype);
2013 }
2015}
2016
2019{
2021
2022 RailType rt;
2023 switch (_settings_client.gui.default_rail_road_type) {
2025 /* Find the most used rail type */
2027
2028 rt = static_cast<RailType>(std::distance(std::begin(c->infrastructure.rail), std::ranges::max_element(c->infrastructure.rail)));
2029 if (c->infrastructure.rail[rt] > 0) break;
2030
2031 /* No rail, just get the first available one */
2032 [[fallthrough]];
2033 }
2035 /* Use first available type */
2036 std::vector<RailType>::const_iterator it = std::find_if(_sorted_railtypes.begin(), _sorted_railtypes.end(),
2037 [](RailType r) { return HasRailTypeAvail(_local_company, r); });
2038 rt = it != _sorted_railtypes.end() ? *it : RAILTYPE_BEGIN;
2039 break;
2040 }
2042 /* Use last available type */
2043 std::vector<RailType>::const_reverse_iterator it = std::find_if(_sorted_railtypes.rbegin(), _sorted_railtypes.rend(),
2044 [](RailType r){ return HasRailTypeAvail(_local_company, r); });
2045 rt = it != _sorted_railtypes.rend() ? *it : RAILTYPE_BEGIN;
2046 break;
2047 }
2048 default:
2049 NOT_REACHED();
2050 }
2051
2053}
2054
2060{
2062
2063 if (new_variant != _cur_signal_variant) {
2064 Window *w = FindWindowById(WindowClass::BuildSignal, 0);
2065 if (w != nullptr) {
2066 w->SetDirty();
2068 }
2069 _cur_signal_variant = new_variant;
2070 }
2071}
2072
2074static const IntervalTimer<TimerGameCalendar> _check_reset_signal{{TimerGameCalendar::Trigger::Year, TimerGameCalendar::Priority::None}, [](auto)
2075{
2076 if (TimerGameCalendar::year != _settings_client.gui.semaphore_build_before) return;
2077
2079}};
2080
2085{
2086 _convert_signal_button = false;
2087 _cur_signal_type = _settings_client.gui.default_signal_type;
2089}
2090
2097DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option)
2098{
2099 RailTypes used_railtypes;
2100 RailTypes avail_railtypes;
2101
2103
2104 /* Find the used railtypes. */
2105 if (for_replacement) {
2106 avail_railtypes = GetCompanyRailTypes(c->index, false);
2107 used_railtypes = GetRailTypes(false);
2108 } else {
2109 avail_railtypes = c->avail_railtypes;
2110 used_railtypes = GetRailTypes(true);
2111 }
2112
2113 DropDownList list;
2114
2115 if (all_option) {
2116 list.push_back(MakeDropDownListStringItem(STR_REPLACE_ALL_RAILTYPE, INVALID_RAILTYPE));
2117 }
2118
2119 Dimension d = { 0, 0 };
2120 /* Get largest icon size, to ensure text is aligned on each menu item. */
2121 if (!for_replacement) {
2122 used_railtypes.Reset(_railtypes_hidden_mask);
2123 for (const auto &rt : _sorted_railtypes) {
2124 if (!used_railtypes.Test(rt)) continue;
2125 const RailTypeInfo *rti = GetRailTypeInfo(rt);
2127 }
2128 }
2129
2130 /* Shared list so that each item can take ownership. */
2131 auto badge_class_list = std::make_shared<GUIBadgeClasses>(GrfSpecFeature::RailTypes);
2132
2133 for (const auto &rt : _sorted_railtypes) {
2134 /* If it's not used ever, don't show it to the user. */
2135 if (!used_railtypes.Test(rt)) continue;
2136
2137 const RailTypeInfo *rti = GetRailTypeInfo(rt);
2138
2139 if (for_replacement) {
2140 list.push_back(MakeDropDownListBadgeItem(badge_class_list, rti->badges, GrfSpecFeature::RailTypes, rti->introduction_date, GetString(rti->strings.replace_text), rt, !avail_railtypes.Test(rt)));
2141 } else {
2142 std::string str = rti->max_speed > 0
2143 ? GetString(STR_TOOLBAR_RAILTYPE_VELOCITY, rti->strings.menu_text, rti->max_speed)
2144 : GetString(rti->strings.menu_text);
2145 list.push_back(MakeDropDownListBadgeIconItem(badge_class_list, rti->badges, GrfSpecFeature::RailTypes, rti->introduction_date, RailBuildCost(rt), d, rti->gui_sprites.build_x_rail, PAL_NONE, std::move(str), rt, !avail_railtypes.Test(rt)));
2146 }
2147 }
2148
2149 if (list.empty()) {
2150 /* Empty dropdowns are not allowed */
2151 list.push_back(MakeDropDownListStringItem(STR_NONE, INVALID_RAILTYPE, true));
2152 }
2153
2154 return list;
2155}
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, RailType railtype, RoadType roadtype)
Prepare the data for the build a bridge window.
bool IsBridgeTile(Tile t)
checks if there is a bridge on this tile
Definition bridge_map.h:35
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Timpl & Reset()
Reset all bits.
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Common return value for all commands.
bool Succeeded() const
Did this command succeed?
bool Failed() const
Did this command fail?
Iterate a range of enum values.
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
const Tspec * GetSpec(uint index) const
Get a spec from the class at a given index.
static std::span< NewGRFClass< StationSpec, StationClassID > const > Classes()
static NewGRFClass * Get(StationClassID class_index)
StationClass::index_type GetClassIndex(int cls_id) const
Definition picker_gui.h:242
const StationClass * GetClass(int cls_id) const
Definition picker_gui.h:249
PickerCallbacksNewGRFClass(const std::string &ini_group)
Definition picker_gui.h:235
const StationClass::spec_type * GetSpec(int cls_id, int id) const
Definition picker_gui.h:257
Base class for windows opened from a toolbar.
Definition window_gui.h:998
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
Definition window.cpp:3622
static constexpr int PREVIEW_WIDTH
Width of each preview button.
Definition picker_gui.h:339
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
static constexpr int PREVIEW_HEIGHT
Height of each preview button.
Definition picker_gui.h:340
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
static constexpr int PREVIEW_LEFT
Offset from left edge to draw preview.
Definition picker_gui.h:341
static constexpr int PREVIEW_BOTTOM
Offset from bottom edge to draw preview.
Definition picker_gui.h:342
@ PCWHK_FOCUS_FILTER_BOX
Focus the edit box for editing the filter string.
Definition picker_gui.h:373
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
void OnInit() override
Notification that the nested widget tree gets initialized.
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.
This struct contains all the info that is needed to draw and construct tracks.
Definition rail.h:117
uint16_t max_speed
Maximum speed for vehicles travelling on this rail type.
Definition rail.h:222
SpriteID build_tunnel
button for building a tunnel
Definition rail.h:150
CursorID rail_swne
Cursor for building rail in X direction.
Definition rail.h:157
SpriteID convert_rail
button for converting rail
Definition rail.h:151
struct RailTypeInfo::@157247141350136173143103254227157213063052244122 strings
Strings associated with the rail type.
CursorID convert
Cursor for converting track.
Definition rail.h:163
CursorID depot
Cursor for building a depot.
Definition rail.h:161
TimerGameCalendar::Date introduction_date
Introduction date.
Definition rail.h:246
CursorID rail_nwse
Cursor for building rail in Y direction.
Definition rail.h:159
SpriteID build_x_rail
button for building single rail in X direction
Definition rail.h:145
CursorID rail_ew
Cursor for building rail in E-W direction.
Definition rail.h:158
SpriteID auto_rail
button for the autorail construction
Definition rail.h:148
CursorID autorail
Cursor for autorail tool.
Definition rail.h:160
StringID menu_text
Name of this rail type in the main toolbar dropdown.
Definition rail.h:169
StringID toolbar_caption
Caption in the construction toolbar GUI for this rail type.
Definition rail.h:168
struct RailTypeInfo::@047376261311064105134233254254216006075341230376 gui_sprites
struct containing the sprites for the rail GUI.
SpriteID build_ew_rail
button for building single rail in E-W direction
Definition rail.h:146
SpriteID build_y_rail
button for building single rail in Y direction
Definition rail.h:147
EnumIndexArray< EnumIndexArray< EnumIndexArray< SpriteID, SignalState, SignalState::End >, SignalVariant, SignalVariant::End >, SignalType, SignalType::End > signals
signal GUI sprites (type, variant, state)
Definition rail.h:152
StringID replace_text
Text used in the autoreplace GUI.
Definition rail.h:171
SpriteID build_depot
button for building depots
Definition rail.h:149
SpriteID build_ns_rail
button for building single rail in N-S direction
Definition rail.h:144
CursorID rail_ns
Cursor for building rail in N-S direction.
Definition rail.h:156
SpriteID tunnel
tunnel sprites base
Definition rail.h:135
struct RailTypeInfo::@057010233226120022371265166156055202241326366156 cursor
Cursors associated with the rail type.
bool IsActive() const override
Should picker class/type selection be enabled?
StringID GetCollectionTooltip() const override
Get the tooltip string for the collection list.
bool HasClassChoice() const override
Are there multiple classes to chose from?
std::span< const BadgeID > GetTypeBadges(int cls_id, int id) const override
Get the item's badges of a type.
StringID GetTypeName(int cls_id, int id) const override
Get the item name of a type.
StringID GetClassTooltip() const override
Get the tooltip string for the class list.
void SetSelectedType(int id) const override
Set the selected type.
void DrawType(int x, int y, int cls_id, int id) const override
Draw preview image of an item.
StringID GetClassName(int id) const override
Get the name of a class.
StringID GetTypeTooltip() const override
Get the tooltip string for the type grid.
int GetSelectedClass() const override
Get the index of the selected class.
void SetSelectedClass(int id) const override
Set the selected class.
GrfSpecFeature GetFeature() const override
NewGRF feature this picker is for.
bool IsTypeAvailable(int cls_id, int id) const override
Test if an item is currently buildable.
int GetSelectedType() const override
Get the selected type.
void FillUsedItems(std::set< PickerItem > &items) override
Fill a set with all items that are used by the current player.
Wrapper class to abstract away the way the tiles are stored.
Definition map_func.h:25
static Year year
Current year, starting at 0.
int GetSelectedType() const override
Get the selected type.
GrfSpecFeature GetFeature() const override
NewGRF feature this picker is for.
void SetSelectedClass(int id) const override
Set the selected class.
StringID GetTypeTooltip() const override
Get the tooltip string for the type grid.
void DrawType(int x, int y, int cls_id, int id) const override
Draw preview image of an item.
StringID GetCollectionTooltip() const override
Get the tooltip string for the collection list.
bool IsTypeAvailable(int cls_id, int id) const override
Test if an item is currently buildable.
void Close(int) override
Hide the window and all its child windows, and mark them for a later deletion.
std::span< const BadgeID > GetTypeBadges(int cls_id, int id) const override
Get the item's badges of a type.
int GetSelectedClass() const override
Get the index of the selected class.
StringID GetTypeName(int cls_id, int id) const override
Get the item name of a type.
bool IsActive() const override
Should picker class/type selection be enabled?
void SetSelectedType(int id) const override
Set the selected type.
StringID GetClassName(int id) const override
Get the name of a class.
StringID GetClassTooltip() const override
Get the tooltip string for the class list.
void FillUsedItems(std::set< PickerItem > &items) override
Fill a set with all items that are used by the current player.
bool HasClassChoice() const override
Are there multiple classes to chose from?
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:30
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition window_gui.h:95
CommandFlags GetCommandFlags(Commands cmd)
Get the command flags associated with the given command.
Definition command.cpp:113
Functions related to commands.
static constexpr DoCommandFlags CommandFlagsToDCFlags(CommandFlags cmd_flags)
Extracts the DC flags needed for DoCommand from the flags returned by GetCommandFlags.
@ Auto
don't allow building on structures
Commands
List of commands.
Definition of stuff that is very close to a company, like the company struct itself.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Functions related to companies.
static constexpr CompanyID COMPANY_SPECTATOR
The client is spectating.
bool IsValidAxis(Axis d)
Checks if an integer value is a valid Axis.
Axis
Enumeration for the two axis X and Y.
@ X
The X axis.
@ Y
The y axis.
DiagDirection
Enumeration for diagonal directions.
@ SW
Southwest.
@ NW
Northwest.
@ NE
Northeast, upper right on your monitor.
@ SE
Southeast.
std::unique_ptr< DropDownListItem > MakeDropDownListStringItem(StringID str, int value, bool masked, bool shaded)
Creates new DropDownListStringItem.
Definition dropdown.cpp:49
Functions related to the drop down widget.
Types related to the drop down widget.
std::vector< std::unique_ptr< const DropDownListItem > > DropDownList
A drop down list is a collection of drop down list items.
Base class for engines.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Definition enum_type.hpp:21
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:88
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Geometry functions.
int CentreBounds(int min, int max, int size)
Determine where to position a centred object.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition gfx.cpp:971
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:39
void SetCursor(CursorID icon, PaletteID pal)
Assign an animation or a non-animated sprite to the cursor.
Definition gfx.cpp:1737
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition gfx.cpp:1037
uint8_t GetDigitWidth(FontSize size)
Return the maximum width of single digit.
Definition gfx.cpp:1290
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:1572
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
@ Normal
Index of the normal font in the font tables.
Definition gfx_type.h:249
uint32_t CursorID
The number of the cursor (sprite).
Definition gfx_type.h:19
@ Invalid
Invalid marker.
Definition gfx_type.h:302
@ Grey
Grey.
Definition gfx_type.h:299
@ DarkGreen
Dark green.
Definition gfx_type.h:292
@ White
White colour.
Definition gfx_type.h:330
@ Orange
Orange colour.
Definition gfx_type.h:324
@ WKC_R_BRACKET
] Right square bracket
Definition gfx_type.h:102
@ WKC_L_BRACKET
[ Left square bracket
Definition gfx_type.h:100
@ WKC_GLOBAL_HOTKEY
Fake keycode bit to indicate global hotkeys.
Definition gfx_type.h:35
constexpr NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
Obtain a nested widget (sub)tree from an external source.
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
constexpr NWidgetPart SetSpriteTip(SpriteID sprite, StringID tip={})
Widget part function for setting the sprite and tooltip.
constexpr NWidgetPart SetToolbarMinimalSize(int width)
Widget part function to setting the minimal size for a toolbar button.
constexpr NWidgetPart SetPIP(uint8_t pre, uint8_t inter, uint8_t post)
Widget part function for setting a pre/inter/post spaces.
constexpr NWidgetPart SetPadding(uint8_t top, uint8_t right, uint8_t bottom, uint8_t left)
Widget part function for setting additional space around a widget.
constexpr NWidgetPart SetStringTip(StringID string, StringID tip={})
Widget part function for setting the string and tooltip.
constexpr NWidgetPart SetAspect(float ratio, AspectFlags flags=AspectFlag::ResizeX)
Widget part function for setting the aspect ratio.
constexpr NWidgetPart SetMinimalTextLines(uint8_t lines, uint8_t spacing, FontSize size=FontSize::Normal)
Widget part function for setting the minimal text lines.
constexpr NWidgetPart SetToolbarSpacerMinimalSize()
Widget part function to setting the minimal size for a toolbar spacer.
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
constexpr NWidgetPart SetToolTip(StringID tip)
Widget part function for setting tooltip and clearing the widget data.
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
constexpr NWidgetPart SetTextStyle(TextColour colour, FontSize size=FontSize::Normal)
Widget part function for setting the text style.
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=INVALID_WIDGET)
Widget part function for starting a new 'real' widget.
constexpr NWidgetPart SetArrowWidgetTypeTip(ArrowWidgetType widget_type, StringID tip={})
Widget part function for setting the arrow widget type and tooltip.
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.
static const CursorID ANIMCURSOR_BUILDSIGNALS
1292 - 1293 - build signal
Definition sprites.h:1692
static const CursorID ANIMCURSOR_DEMOLISH
704 - 707 - demolish dynamite
Definition sprites.h:1688
static const CursorID SPR_CURSOR_RAIL_STATION
Definition sprites.h:1618
static const CursorID SPR_CURSOR_BRIDGE
Definition sprites.h:1594
static const CursorID SPR_CURSOR_WAYPOINT
Definition sprites.h:1630
void SetDirty() const
Mark entire window as dirty (in need of re-paint).
Definition window.cpp:972
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1553
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.
std::tuple< size_t, size_t > GetListIndexStep(SpecialListHotkeys hotkey, const ListType &list, const ItemType &current_item)
Gets the first index in the list for given hotkey and the step to look for another if first is invali...
Definition hotkeys.h:110
SpecialListHotkeys
Indexes for special hotkeys to navigate in lists.
Definition hotkeys.h:93
@ NextItem
Hotkey to select next item in the list.
Definition hotkeys.h:95
@ FirstItem
Hotkey to select first item in the list.
Definition hotkeys.h:96
@ LastItem
Hotkey to select last item in the list.
Definition hotkeys.h:97
@ PreviousItem
Hotkey to select previous item in the list.
Definition hotkeys.h:94
bool IsSpecialHotkey(const int &hotkey)
Checks if hotkey index is special or not.
Definition hotkeys.h:84
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, RoadTramType sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
@ Rail
Rail livery schemes.
Definition livery.h:69
#define Point
Macro that prevents name conflicts between included headers.
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
static TileIndex TileVirtXY(uint x, uint y)
Get a tile from the virtual XY-coordinate.
Definition map_func.h:407
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:574
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
void GuiShowTooltips(Window *parent, EncodedString &&text, TooltipCloseCondition close_tooltip)
Shows a tooltip.
Definition misc_gui.cpp:690
GrfSpecFeature
Definition newgrf.h:78
@ RailTypes
Rail types feature.
Definition newgrf.h:95
@ Stations
Stations feature.
Definition newgrf.h:83
Functions related to NewGRF badges.
int DrawBadgeNameList(Rect r, std::span< const BadgeID > badges, GrfSpecFeature)
Draw names for a list of badge labels.
GUI functions related to NewGRF badges.
@ Avail
Availability of station in construction window.
@ CBID_STATION_AVAILABILITY
Determine whether a newstation should be made available to build.
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.
@ Any
Use first found.
bool IsWaypointClass(const RoadStopClass &cls)
Test if a RoadStopClass is the waypoint class.
bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station)
Draw representation of a station tile for GUI purposes.
Header file for NewGRF stations.
static constexpr StationClassID STAT_CLASS_DFLT
Default station class.
PoolID< uint16_t, struct StationClassIDTag, UINT16_MAX, UINT16_MAX > StationClassID
Class IDs for stations.
static constexpr StationClassID STAT_CLASS_WAYP
Waypoint class.
uint32_t GrfID
The unique identifier of a NewGRF.
Definition newgrf_type.h:15
@ Normal
Playing a game.
Definition openttd.h:20
@ Menu
In the main menu.
Definition openttd.h:19
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.
RailTypes GetCompanyRailTypes(CompanyID company, bool introduces)
Get the rail types the given company can build.
Definition rail.cpp:137
bool HasRailTypeAvail(const CompanyID company, const RailType railtype)
Finds out if a company has a certain buildable railtype available.
Definition rail.cpp:70
RailTypes GetRailTypes(bool introduces)
Get list of rail types, regardless of company availability.
Definition rail.cpp:168
bool ValParamRailType(const RailType rail)
Validate functions for rail building.
Definition rail.cpp:92
void DrawTrainDepotSprite(int x, int y, DiagDirection dir, RailType railtype)
Draw train depot sprite in the UI.
Money RailBuildCost(RailType railtype)
Returns the cost of building the specified railtype.
Definition rail.h:431
std::vector< RailType > _sorted_railtypes
Sorted list of rail types.
Definition rail_cmd.cpp:47
const RailTypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition rail.h:303
Command definitions for rail.
static constexpr std::initializer_list< NWidgetPart > _nested_signal_builder_widgets
Nested widget definition of the build signal window.
Window * ShowBuildRailToolbar(RailType railtype)
Open the build rail toolbar window for a specific rail type.
Definition rail_gui.cpp:975
static constexpr std::array< DiagDirectionIndexArray< DiagDirection >, 3 > _place_depot_extra_dir
Direction to check for existing track pieces.
Definition rail_gui.cpp:139
static bool RailToolbar_CtrlChanged(Window *w)
Updates the Remove button because of Ctrl state change.
Definition rail_gui.cpp:340
void ResetSignalVariant(int32_t)
Updates the current signal variant used in the signal GUI to the one adequate to current year.
static void PlaceRail_Waypoint(TileIndex tile)
Place a rail waypoint.
Definition rail_gui.cpp:170
static RailType _cur_railtype
Rail type of the current build-rail toolbar.
Definition rail_gui.cpp:57
static WindowDesc _station_builder_desc(WindowPosition::Automatic, "build_station_rail", 0, 0, WindowClass::BuildStation, WindowClass::BuildToolbar, WindowDefaultFlag::Construction, _nested_station_builder_widgets, &BuildRailStationWindow::hotkeys)
High level window description of the station-build window (default & newGRF).
static WindowDesc _build_rail_desc(WindowPosition::Manual, "toolbar_rail", 0, 0, WindowClass::BuildToolbar, WindowClass::None, WindowDefaultFlag::Construction, _nested_build_rail_widgets, &BuildRailToolbarWindow::hotkeys)
Window definition for the rail toolbar.
static void HandleAutoSignalPlacement()
Build new signals or remove signals or (if only one tile marked) edit a signal.
Definition rail_gui.cpp:419
static SignalVariant _cur_signal_variant
set the signal variant (for signal GUI)
Definition rail_gui.cpp:61
static WindowDesc _build_depot_desc(WindowPosition::Automatic, {}, 0, 0, WindowClass::BuildDepot, WindowClass::BuildToolbar, WindowDefaultFlag::Construction, _nested_build_depot_widgets)
Window definition for the build rail depot window.
void SetDefaultRailGui()
Set the initial (default) railtype to use.
static void PlaceExtraDepotRail(TileIndex tile, DiagDirection dir, Track track)
Try to add an additional rail-track at the entrance of a depot.
Definition rail_gui.cpp:122
static void PlaceRail_Bridge(TileIndex tile, Window *w)
Start placing a rail bridge.
Definition rail_gui.cpp:296
static const IntervalTimer< TimerGameCalendar > _check_reset_signal
Yearly time to check whether to set the signal variant to electric signals.
static void PlaceRail_Station(TileIndex tile)
Place a rail station.
Definition rail_gui.cpp:202
static StationPickerSelection _station_gui
Settings of the station picker.
Definition rail_gui.cpp:75
static SignalType _cur_signal_type
set the signal type (for signal GUI)
Definition rail_gui.cpp:62
static void ToggleRailButton_Remove(Window *w)
Toggles state of the Remove button of Build rail toolbar.
Definition rail_gui.cpp:326
DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option)
Create a drop down list for all the rail types of the local company.
void CcBuildRailTunnel(Commands, const CommandCost &result, TileIndex tile)
Command callback for building a tunnel.
Definition rail_gui.cpp:312
static void BuildRailClick_Remove(Window *w)
The "remove"-button click proc of the build-rail toolbar.
Definition rail_gui.cpp:361
static constexpr std::array< DiagDirectionIndexArray< Track >, 3 > _place_depot_extra_track
Additional pieces of track to add at the entrance of a depot.
Definition rail_gui.cpp:132
static constexpr std::initializer_list< NWidgetPart > _nested_build_depot_widgets
Nested widget definition of the build rail depot window.
static bool IsStationAvailable(const StationSpec *statspec)
Check whether a station type can be build.
Definition rail_gui.cpp:89
static WindowDesc _signal_builder_desc(WindowPosition::Automatic, {}, 0, 0, WindowClass::BuildSignal, WindowClass::BuildToolbar, WindowDefaultFlag::Construction, _nested_signal_builder_widgets)
Signal selection window description.
static Window * ShowStationBuilder(Window *parent)
Open station build window.
static bool StationUsesDefaultType(const BaseStation *bst)
Test if a station/waypoint uses the default graphics.
static DiagDirection _build_depot_direction
Currently selected depot direction.
Definition rail_gui.cpp:59
void InitializeRailGui()
Initialize rail building GUI settings.
static void ShowSignalBuilder(Window *parent)
Open the signal selection window.
static WindowDesc _build_waypoint_desc(WindowPosition::Automatic, "build_waypoint", 0, 0, WindowClass::BuildWaypoint, WindowClass::BuildToolbar, WindowDefaultFlag::Construction, _nested_build_waypoint_widgets, &BuildRailWaypointWindow::hotkeys)
Window definition for the build rail waypoint window.
static constexpr std::initializer_list< NWidgetPart > _nested_build_waypoint_widgets
Nested widget definition for the build NewGRF rail waypoint window.
static bool _remove_button_clicked
Flag whether 'remove' toggle-button is currently enabled.
Definition rail_gui.cpp:58
void ReinitGuiAfterToggleElrail(bool disable)
Re-initialize rail-build toolbar after toggling support for electric trains.
void InitializeSignalGui()
Resets the signal GUI.
static bool _convert_signal_button
convert signal button in the signal GUI pressed
Definition rail_gui.cpp:60
static void GenericPlaceSignals(TileIndex tile)
Build a new signal or edit/remove a present signal, use CmdBuildSingleSignal() or CmdRemoveSingleSign...
Definition rail_gui.cpp:238
static WaypointPickerSelection _waypoint_gui
Settings of the waypoint picker.
Definition rail_gui.cpp:68
Functions/types etc.
@ SIGNAL_GUI_ALL
Show all signals, including block and presignals.
Definition rail_gui.h:26
@ SIGNAL_CYCLE_ALL
Cycle through all signals visible to the player.
Definition rail_gui.h:32
static RailTileType GetRailTileType(Tile t)
Returns the RailTileType (normal with or without signals, waypoint or depot).
Definition rail_map.h:36
TrackBits GetTrackBits(Tile tile)
Gets the track bits of the given tile.
Definition rail_map.h:136
static bool IsPlainRailTile(Tile t)
Checks whether the tile is a rail tile or rail tile with signals.
Definition rail_map.h:60
@ Depot
Depot (one entrance).
Definition rail_map.h:26
@ Signals
Normal rail tile with signals.
Definition rail_map.h:25
bool HasSignalOnTrack(Tile tile, Track track)
Checks for the presence of signals (either way) on the given track on the given rail tile.
Definition rail_map.h:474
SignalType GetSignalType(Tile t, Track track)
Get the signal type for a track on a tile.
Definition rail_map.h:303
static bool IsRailDepotTile(Tile t)
Is this tile rail tile and a rail depot?
Definition rail_map.h:105
EnumBitSet< RailType, uint64_t > RailTypes
Bitset of RailType elements.
Definition rail_type.h:36
RailType
Enumeration for all possible railtypes.
Definition rail_type.h:25
@ RAILTYPE_BEGIN
Used for iterations.
Definition rail_type.h:26
@ INVALID_RAILTYPE
Flag for invalid railtype.
Definition rail_type.h:32
@ RAILTYPE_ELECTRIC
Electric rails.
Definition rail_type.h:28
@ RAILTYPE_RAIL
Standard non-electric rails.
Definition rail_type.h:27
Types related to the rail widgets.
@ WID_RAT_BUILD_SIGNALS
Build signals.
Definition rail_widget.h:26
@ WID_RAT_BUILD_NS
Build rail along the game view Y axis.
Definition rail_widget.h:17
@ WID_RAT_CONVERT_RAIL
Convert other rail to this type.
Definition rail_widget.h:30
@ WID_RAT_BUILD_Y
Build rail along the game grid Y axis.
Definition rail_widget.h:20
@ WID_RAT_BUILD_EW
Build rail along the game view X axis.
Definition rail_widget.h:19
@ WID_RAT_BUILD_BRIDGE
Build a bridge.
Definition rail_widget.h:27
@ WID_RAT_REMOVE
Bulldozer to remove rail.
Definition rail_widget.h:29
@ WID_RAT_CAPTION
Caption of the window.
Definition rail_widget.h:16
@ WID_RAT_BUILD_WAYPOINT
Build a waypoint.
Definition rail_widget.h:24
@ WID_RAT_BUILD_DEPOT
Build a depot.
Definition rail_widget.h:23
@ WID_RAT_DEMOLISH
Destroy something with dynamite!
Definition rail_widget.h:22
@ WID_RAT_BUILD_STATION
Build a station.
Definition rail_widget.h:25
@ WID_RAT_BUILD_X
Build rail along the game grid X axis.
Definition rail_widget.h:18
@ WID_RAT_BUILD_TUNNEL
Build a tunnel.
Definition rail_widget.h:28
@ WID_RAT_AUTORAIL
Autorail tool.
Definition rail_widget.h:21
@ WID_BRAS_HIGHLIGHT_OFF
Button for turning coverage highlighting off.
Definition rail_widget.h:57
@ WID_BRAS_PLATFORM_NUM_4
Button to select stations with 4 platforms.
Definition rail_widget.h:42
@ WID_BRAS_PLATFORM_NUM_7
Button to select stations with 7 platforms.
Definition rail_widget.h:45
@ WID_BRAS_PLATFORM_DIR_X
Button to select '/' view.
Definition rail_widget.h:36
@ WID_BRAS_PLATFORM_LEN_BEGIN
Helper for determining the chosen platform length.
Definition rail_widget.h:62
@ WID_BRAS_PLATFORM_LEN_3
Button to select 3 tiles length station platforms.
Definition rail_widget.h:49
@ WID_BRAS_PLATFORM_DIR_Y
Button to select '\' view.
Definition rail_widget.h:37
@ WID_BRAS_PLATFORM_LEN_6
Button to select 6 tiles length station platforms.
Definition rail_widget.h:52
@ WID_BRAS_PLATFORM_NUM_1
Button to select stations with a single platform.
Definition rail_widget.h:39
@ WID_BRAS_PLATFORM_NUM_BEGIN
Helper for determining the chosen platform width.
Definition rail_widget.h:61
@ WID_BRAS_PLATFORM_NUM_3
Button to select stations with 3 platforms.
Definition rail_widget.h:41
@ WID_BRAS_PLATFORM_LEN_5
Button to select 5 tiles length station platforms.
Definition rail_widget.h:51
@ WID_BRAS_PLATFORM_NUM_5
Button to select stations with 5 platforms.
Definition rail_widget.h:43
@ WID_BRAS_COVERAGE_TEXTS
Empty space for the coverage texts.
Definition rail_widget.h:59
@ WID_BRAS_PLATFORM_LEN_1
Button to select single tile length station platforms.
Definition rail_widget.h:47
@ WID_BRAS_HIGHLIGHT_ON
Button for turning coverage highlighting on.
Definition rail_widget.h:58
@ WID_BRAS_PLATFORM_DRAG_N_DROP
Button to enable drag and drop type station placement.
Definition rail_widget.h:55
@ WID_BRAS_PLATFORM_LEN_7
Button to select 7 tiles length station platforms.
Definition rail_widget.h:53
@ WID_BRAS_PLATFORM_NUM_6
Button to select stations with 6 platforms.
Definition rail_widget.h:44
@ WID_BRAS_PLATFORM_NUM_2
Button to select stations with 2 platforms.
Definition rail_widget.h:40
@ WID_BRAS_PLATFORM_LEN_4
Button to select 4 tiles length station platforms.
Definition rail_widget.h:50
@ WID_BRAS_PLATFORM_LEN_2
Button to select 2 tiles length station platforms.
Definition rail_widget.h:48
@ WID_BRAD_DEPOT_SE
Build a depot with the entrance in the south east.
Definition rail_widget.h:92
@ WID_BRAD_DEPOT_NE
Build a depot with the entrance in the north east.
Definition rail_widget.h:91
@ WID_BRAD_DEPOT_SW
Build a depot with the entrance in the south west.
Definition rail_widget.h:93
@ WID_BRAD_DEPOT_NW
Build a depot with the entrance in the north west.
Definition rail_widget.h:94
@ WID_BS_DRAG_SIGNALS_DENSITY_DECREASE
Decrease the signal density.
Definition rail_widget.h:82
@ WID_BS_ELECTRIC_PBS
Build an electric path signal.
Definition rail_widget.h:78
@ WID_BS_SEMAPHORE_NORM
Build a semaphore normal block signal.
Definition rail_widget.h:68
@ WID_BS_ELECTRIC_NORM
Build an electric normal block signal.
Definition rail_widget.h:74
@ WID_BS_ELECTRIC_EXIT
Build an electric exit block signal.
Definition rail_widget.h:76
@ WID_BS_ELECTRIC_ENTRY
Build an electric entry block signal.
Definition rail_widget.h:75
@ WID_BS_SEMAPHORE_ENTRY
Build a semaphore entry block signal.
Definition rail_widget.h:69
@ WID_BS_BLOCK_SEL
Container for the block signal group, which can be hidden.
Definition rail_widget.h:84
@ WID_BS_CAPTION
Caption for the Signal Selection window.
Definition rail_widget.h:67
@ WID_BS_SEMAPHORE_COMBO
Build a semaphore combo block signal.
Definition rail_widget.h:71
@ WID_BS_BLOCK_SPACER_SEL
Container for the spacer between block and path signal groups, which can be hidden.
Definition rail_widget.h:85
@ WID_BS_SEMAPHORE_PBS
Build a semaphore path signal.
Definition rail_widget.h:72
@ WID_BS_DRAG_SIGNALS_DENSITY_LABEL
The current signal density.
Definition rail_widget.h:81
@ WID_BS_SEMAPHORE_EXIT
Build a semaphore exit block signal.
Definition rail_widget.h:70
@ WID_BS_SEMAPHORE_PBS_OWAY
Build a semaphore one way path signal.
Definition rail_widget.h:73
@ WID_BS_DRAG_SIGNALS_DENSITY_INCREASE
Increase the signal density.
Definition rail_widget.h:83
@ WID_BS_CONVERT
Convert the signal.
Definition rail_widget.h:80
@ WID_BS_ELECTRIC_COMBO
Build an electric combo block signal.
Definition rail_widget.h:77
@ WID_BS_ELECTRIC_PBS_OWAY
Build an electric one way path signal.
Definition rail_widget.h:79
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:28
@ Invalid
Invalid marker.
Definition road_type.h:41
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:61
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
@ LastAvailable
Use the latest available to the player.
@ FirstAvailable
Use the first available to the player.
@ MostUsed
Use the most used by the company controlled by the player.
SignalType
Type of signal, i.e.
Definition signal_type.h:24
@ End
End marker.
Definition signal_type.h:31
@ Path
normal path signal.
Definition signal_type.h:29
@ PathOneWay
no-entry path signal.
Definition signal_type.h:30
@ Combo
presignal inter-block.
Definition signal_type.h:28
@ Block
block signal.
Definition signal_type.h:25
SignalState
These are states in which a signal can be.
Definition signal_type.h:40
@ Green
The signal is green.
Definition signal_type.h:42
@ Red
The signal is red.
Definition signal_type.h:41
SignalVariant
Variant of the signal, i.e.
Definition signal_type.h:16
@ Electric
Light signal.
Definition signal_type.h:17
@ Semaphore
Old-fashioned semaphore signal.
Definition signal_type.h:18
void SndClickBeep()
Play a beep sound for a click event if enabled in settings.
Definition sound.cpp:254
Functions related to sound.
@ SND_20_CONSTRUCTION_RAIL
30 == 0x1E Construction: rail infrastructure
Definition sound_type.h:78
static const SpriteID SPR_IMG_RAIL_NS
Definition sprites.h:1494
static const SpriteID SPR_IMG_RAIL_NE
Definition sprites.h:1495
static const SpriteID SPR_IMG_CONVERT_RAIL
Definition sprites.h:1531
static const SpriteID SPR_IMG_DEPOT_RAIL
Definition sprites.h:1505
static const SpriteID SPR_IMG_RAIL_STATION
Definition sprites.h:1510
static const SpriteID SPR_IMG_DYNAMITE
Definition sprites.h:1230
static const SpriteID SPR_IMG_SIGNAL_CONVERT
Definition sprites.h:1525
static const SpriteID SPR_IMG_REMOVE
Definition sprites.h:1480
static const SpriteID SPR_IMG_TUNNEL_RAIL
Definition sprites.h:1527
static const SpriteID SPR_IMG_RAIL_NW
Definition sprites.h:1497
static const SpriteID SPR_IMG_RAIL_SIGNALS
Definition sprites.h:1511
static const SpriteID SPR_IMG_AUTORAIL
Definition sprites.h:1498
static const SpriteID SPR_IMG_BRIDGE
Definition sprites.h:1478
static const SpriteID SPR_IMG_RAIL_EW
Definition sprites.h:1496
static const SpriteID SPR_IMG_WAYPOINT
Definition sprites.h:1503
Base classes/functions for stations.
Command definitions related to stations.
void ShowSelectStationIfNeeded(TileArea ta, StationPickerCmdProc proc)
Show the station selection window when needed.
void ShowSelectRailWaypointIfNeeded(TileArea ta, StationPickerCmdProc proc)
Show the rail waypoint selection window when needed.
int DrawStationCoverageAreaText(const Rect &r, StationCoverageType sct, int rad, bool supplies)
Calculates and draws the accepted or supplied cargo around the selected tile(s).
void CheckRedrawStationCoverage(const Window *w)
Check whether we need to redraw the station coverage text.
Contains enums and function declarations connected with stations GUI.
@ SCT_ALL
Draw all cargoes.
Definition station_gui.h:24
Maps accessors for stations.
uint GetCustomStationSpecIndex(Tile t)
Get the custom station spec for this tile.
bool HasStationRail(Tile t)
Has this station tile a rail?
static constexpr uint CA_TRAIN
Catchment for train stations with "modified catchment" enabled.
@ Rail
Railways/train station.
static constexpr uint CA_UNMODIFIED
Catchment for all stations with "modified catchment" disabled.
Definition of base types and functions in a cross-platform compatible way.
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:424
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...
Base class for all station-ish types.
TileArea train_station
Tile area the train 'station' part covers.
virtual bool TileBelongsToRailStation(TileIndex tile) const =0
Check whether a specific tile belongs to this station.
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 OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
void SetSelectedSize()
Set the build station tile highlight to current station size.
void OnRealtimeTick(uint delta_ms) override
Called periodically.
void OnPaint() override
The window must be repainted.
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.
static EventState BuildRailStationGlobalHotkeys(int hotkey)
Handler for global hotkeys of the BuildRailStationWindow.
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.
uint coverage_height
Height of the coverage texts.
void CheckSelectedSize(const StationSpec *statspec)
Verify whether the currently selected station size is allowed after selecting a new station class/typ...
void OnInit() override
Notification that the nested widget tree gets initialized.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Rail toolbar management class.
Definition rail_gui.cpp:444
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 rail_gui.cpp:838
RailType railtype
Rail type to build.
Definition rail_gui.cpp:445
void OnRealtimeTick(uint delta_ms) override
Called periodically.
Definition rail_gui.cpp:851
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition rail_gui.cpp:474
WidgetID last_user_action
Last started user action.
Definition rail_gui.cpp:446
void ModifyRailType(RailType railtype)
Switch to another rail type.
Definition rail_gui.cpp:534
void OnInit() override
Notification that the nested widget tree gets initialized.
Definition rail_gui.cpp:516
bool OnTooltip(Point pt, WidgetID widget, TooltipCloseCondition close_cond) override
Event to display a custom tooltip.
Definition rail_gui.cpp:505
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition rail_gui.cpp:634
EventState OnCTRLStateChange() override
The state of the control key has changed.
Definition rail_gui.cpp:844
CursorID GetCursorForWidget(WidgetID widget)
Returns corresponding cursor for provided button.
Definition rail_gui.cpp:588
EventState ChangeRailTypeOnHotkey(int hotkey)
Selects new RailType based on SpecialHotkeys and order defined in _sorted_railtypes.
Definition rail_gui.cpp:861
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
Definition rail_gui.cpp:570
void OnPlaceObjectAbort() override
The user cancelled a tile highlight mode that has been set.
Definition rail_gui.cpp:821
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 rail_gui.cpp:746
static EventState RailToolbarGlobalHotkeys(int hotkey)
Handler for global hotkeys of the BuildRailToolbarWindow.
Definition rail_gui.cpp:886
void OnPlaceObject(Point pt, TileIndex tile) override
The user clicked some place on the map when a tile highlight mode has been set.
Definition rail_gui.cpp:687
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 rail_gui.cpp:759
static const std::initializer_list< WidgetID > can_build_widgets
List of widgets to be disabled if infrastructure limit prevents building.
Definition rail_gui.cpp:468
Point OnInitialPosition(int16_t sm_width, int16_t sm_height, int window_number) override
Compute the initial position of the window.
Definition rail_gui.cpp:754
EventState OnHotkey(int hotkey) override
A hotkey has been pressed.
Definition rail_gui.cpp:680
HighLightStyle GetHighLightStyleForWidget(WidgetID widget)
Returns corresponding high light style for provided button.
Definition rail_gui.cpp:613
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
Definition rail_gui.cpp:458
Dimension sig_sprite_size
Maximum size of signal GUI sprites.
void DrawSignalSprite(const Rect &r, SpriteID image) const
Draw dynamic a signal-sprite in a button in the signal GUI.
void SetSignalUIMode()
Show or hide buttons for non-path signals in the signal GUI.
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
void OnInit() override
Notification that the nested widget tree gets initialized.
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.
int sig_sprite_bottom_offset
Maximum extent of signal GUI sprite from reference point towards bottom.
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
std::array< uint32_t, RAILTYPE_END > rail
Count of company owned track bits for each rail type.
CompanyInfrastructure infrastructure
NOSAVE: Counts of company owned infrastructure.
RailTypes avail_railtypes
Rail types available to this company.
T y
Y coordinate.
T x
X coordinate.
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
List of hotkeys for a window.
Definition hotkeys.h:46
All data for a single hotkey.
Definition hotkeys.h:22
uint16_t w
The width of the area.
TileIndex tile
The base tile of the area.
uint16_t h
The height of the area.
static Company * Get(auto index)
Specification of a rectangle with absolute coordinates of all edges.
int Width() const
Get width of Rect.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
int Height() const
Get height of Rect.
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
StationClassID sel_class
Selected station class.
Definition rail_gui.cpp:71
uint16_t sel_type
Selected station type within the class.
Definition rail_gui.cpp:72
Axis axis
Selected orientation of the station.
Definition rail_gui.cpp:73
Station specification.
uint8_t disallowed_lengths
Bitmask of platform lengths available for the station.
uint8_t disallowed_platforms
Bitmask of number of platforms available for the station.
CargoGRFFileProps grf_prop
Link to NewGRF.
StationCallbackMasks callback_mask
Bitmask of station callbacks that have to be called.
Station data structure.
StationClassID sel_class
Selected station class.
Definition rail_gui.cpp:65
uint16_t sel_type
Selected station type within the class.
Definition rail_gui.cpp:66
Representation of a waypoint.
High level window description.
Definition window_gui.h:172
Data structure for an opened window.
Definition window_gui.h:273
void ReInit(int rx=0, int ry=0, bool reposition=false)
Re-initialize a window, and optionally change its size.
Definition window.cpp:984
virtual void Close(int data=0)
Hide the window and all its child windows, and mark them for a later deletion.
Definition window.cpp:1109
virtual void OnInvalidateData(int data=0, bool gui_scope=true)
Some data on this window has become invalid.
Definition window_gui.h:798
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1814
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:792
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing).
Definition window.cpp:3255
Window * parent
Parent window.
Definition window_gui.h:328
void RaiseWidget(WidgetID widget_index)
Marks a widget as raised.
Definition window_gui.h:469
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:562
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
Definition window.cpp:510
ResizeInfo resize
Resize information.
Definition window_gui.h:314
void DisableWidget(WidgetID widget_index)
Sets a widget to disabled.
Definition window_gui.h:391
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1804
bool IsWidgetLowered(WidgetID widget_index) const
Gets the lowered state of a widget.
Definition window_gui.h:491
bool IsWidgetDisabled(WidgetID widget_index) const
Gets the enabled/disabled status of a widget.
Definition window_gui.h:410
void RaiseButtons(bool autoraise=false)
Raise the buttons of the window.
Definition window.cpp:536
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition window_gui.h:441
bool IsShaded() const
Is window shaded currently?
Definition window_gui.h:562
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:849
Window(WindowDesc &desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
Definition window.cpp:1838
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:989
void LowerWidget(WidgetID widget_index)
Marks a widget as lowered.
Definition window_gui.h:460
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition window.cpp:1828
virtual EventState OnHotkey(int hotkey)
A hotkey has been pressed.
Definition window.cpp:576
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:381
void ToggleWidgetLoweredState(WidgetID widget_index)
Invert the lowered/raised status of a widget.
Definition window_gui.h:450
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:302
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.
static bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition tile_map.h:161
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:92
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:100
@ Railway
A tile with railway.
Definition tile_type.h:50
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
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)
Prepare state for highlighting tiles while dragging with the mouse.
HighLightStyle
Highlighting draw styles.
@ HT_LINE
used for autorail highlighting (longer stretches), lower bits: direction
@ HT_DIR_HL
horizontal lower
@ HT_DIR_X
X direction.
@ HT_DIAGONAL
Also allow 'diagonal rectangles'. Only usable in combination with HT_RECT or HT_POINT.
@ HT_RECT
rectangle (stations, depots, ...)
@ HT_DIR_MASK
masks the drag-direction
@ HT_RAIL
autorail (one piece), lower bits: direction
@ HT_DRAG_MASK
Mask for the tile drag-type modes.
@ HT_DIR_VL
vertical left
@ HT_SPECIAL
special mode used for highlighting while dragging (and for tunnels/docks)
@ HT_DIR_Y
Y direction.
Definition of Interval and OneShot timers.
Definition of the game-calendar-timer.
RailType _last_built_railtype
The most recently used type of rail.
Stuff related to the (main) toolbar.
bool IsValidTrack(Track track)
Checks if a Track is valid.
Definition track_func.h:24
Track FindFirstTrack(TrackBits tracks)
Returns first Track from TrackBits or Track::Invalid.
Definition track_func.h:150
TrackBits DiagdirReachesTracks(DiagDirection diagdir)
Returns all tracks that can be reached when entering a tile from a given (diagonal) direction.
Definition track_func.h:468
TrackBits TrackdirBitsToTrackBits(TrackdirBits bits)
Discards all directional information from a TrackdirBits value.
Definition track_func.h:281
static constexpr TrackBits TRACK_BIT_HORZ
Upper and lower track.
Definition track_type.h:46
EnumBitSet< Track, uint8_t > TrackBits
Bitset of Track elements.
Definition track_type.h:43
static constexpr TrackBits TRACK_BIT_VERT
Left and right track.
Definition track_type.h:47
Track
These are used to specify a single track.
Definition track_type.h:19
@ X
Track along the x-axis (north-east to south-west).
Definition track_type.h:21
@ Upper
Track in the upper corner of the tile (north).
Definition track_type.h:23
@ Y
Track along the y-axis (north-west to south-east).
Definition track_type.h:22
@ Right
Track in the right corner of the tile (east).
Definition track_type.h:26
@ Left
Track in the left corner of the tile (west).
Definition track_type.h:25
@ Lower
Track in the lower corner of the tile (south).
Definition track_type.h:24
TransportType
Available types of transport.
@ Rail
Transport by train.
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.
TileIndex GetOtherTunnelBridgeEnd(Tile t)
Determines type of the wormhole and returns its other end.
bool CanBuildVehicleInfrastructure(VehicleType type, RoadTramType subtype)
Check whether we can build infrastructure for the given vehicle type.
Definition vehicle.cpp:1948
Functions related to vehicles.
@ Train
Train vehicle type.
void SetTileSelectSize(int w, int h)
Highlight w by h tiles at the cursor.
void SetViewportCatchmentWaypoint(const Waypoint *wp, bool sel)
Select or deselect waypoint for coverage area highlight.
void SetRedErrorSquare(TileIndex tile)
Set a tile to display a red error square.
void SetViewportCatchmentStation(const Station *st, bool sel)
Select or deselect station for coverage area highlight.
Functions related to (drawing on) viewports.
ViewportPlaceMethod
Viewport place method (type of highlighted area and placed objects).
@ VPM_FIX_Y
drag only in Y axis
@ VPM_Y_LIMITED
Drag only in Y axis with limited size.
@ VPM_X_AND_Y_LIMITED
area of land of limited size
@ VPM_FIX_VERTICAL
drag only in vertical direction
@ 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_HORIZONTAL
drag only in horizontal direction
@ VPM_FIX_X
drag only in X axis
@ VPM_SIGNALDIRS
similar to VMP_RAILDIRS, but with different cursor
@ VPM_X_OR_Y
drag in X or Y direction
@ VPM_RAILDIRS
all rail directions
ViewportDragDropSelectionProcess
Drag and drop selection process, or, what to do with an area of land when you've selected it.
@ DDSP_CONVERT_RAIL
Rail conversion.
@ DDSP_DEMOLISH_AREA
Clear area.
@ DDSP_BUILD_SIGNALS
Signal placement.
@ DDSP_REMOVE_STATION
Station removal.
@ DDSP_BUILD_STATION
Station placement.
@ DDSP_BUILD_BRIDGE
Bridge placement.
@ DDSP_PLACE_RAIL
Rail placement.
void DrawWaypointSprite(int x, int y, StationClassID station_class, uint16_t station_type, RailType railtype)
Draw a waypoint.
Definition waypoint.cpp:28
Base of waypoints.
@ WPF_ROAD
This is a road waypoint.
Axis GetAxisForNewRailWaypoint(TileIndex tile)
Get the axis for a new rail 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:49
@ WWT_IMGBTN
(Toggle) Button with image
Definition widget_type.h:41
@ WWT_PUSHARROWBTN
Normal push-button (no toggle button) with arrow caption.
@ WWT_LABEL
Centered label.
Definition widget_type.h:48
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:66
@ WWT_TEXTBTN
(Toggle) Button with text
Definition widget_type.h:44
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:39
@ WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX).
Definition widget_type.h:57
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX).
Definition widget_type.h:55
@ WWT_CAPTION
Window caption (window title between closebox and stickybox).
Definition widget_type.h:52
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:68
@ WWT_CLOSEBOX
Close box (at top-left of a window).
Definition widget_type.h:60
@ WWT_EMPTY
Empty widget, place holder to reserve space in widget tree.
Definition widget_type.h:37
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX).
Definition widget_type.h:56
@ NWID_HORIZONTAL_LTR
Horizontal container that doesn't change the order of the widgets for RTL languages.
Definition widget_type.h:67
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:71
@ SZSP_NONE
Display plane with zero size in both directions (none filling and resizing).
@ EqualSize
Containers should keep all their (resizing) children equally large.
@ Decrease
Arrow to the left or in case of RTL to the right.
Definition widget_type.h:20
@ Increase
Arrow to the right or in case of RTL to the left.
Definition widget_type.h:21
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition window.cpp:1201
void CloseWindowByClass(WindowClass cls, int data)
Close all windows of a given class.
Definition window.cpp:1214
Window * BringWindowToFrontById(WindowClass cls, WindowNumber number)
Find a window and make it the relative top-window on the screen.
Definition window.cpp:1285
Point AlignInitialConstructionToolbar(int window_width)
Compute the position of the construction toolbars.
Definition window.cpp:1707
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition window.cpp:1158
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting).
Definition window.cpp:3193
Window functions not directly related to making/drawing windows.
Functions, definitions and such used only by the GUI.
@ Construction
This window is used for construction; close it whenever changing company.
Definition window_gui.h:155
TooltipCloseCondition
Definition window_gui.h:263
@ Automatic
Find a place automatically.
Definition window_gui.h:146
@ Manual
Manually align the window (so no automatic location finding).
Definition window_gui.h:145
int WidgetID
Widget ID.
Definition window_type.h:21
EventState
State of handling an event.
@ Handled
The passed event is handled.
@ NotHandled
The passed event is not handled.
static constexpr WidgetID INVALID_WIDGET
An invalid widget index.
Definition window_type.h:24
Functions related to zooming.
int ScaleSpriteTrad(int value)
Scale traditional pixel dimensions to GUI zoom level, for drawing sprites.
Definition zoom_func.h:107