OpenTTD Source 20260206-master-g4d4e37dbf1
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
88static bool IsStationAvailable(const StationSpec *statspec)
89{
90 if (statspec == nullptr || !statspec->callback_mask.Test(StationCallbackMask::Avail)) return true;
91
92 uint16_t cb_res = GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, nullptr, INVALID_TILE);
93 if (cb_res == CALLBACK_FAILED) return true;
94
96}
97
98void CcPlaySound_CONSTRUCTION_RAIL(Commands, const CommandCost &result, TileIndex tile)
99{
100 if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile);
101}
102
103static void GenericPlaceRail(TileIndex tile, Track track)
104{
106 Command<Commands::RemoveRail>::Post(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL,
107 tile, track);
108 } else {
109 Command<Commands::BuildRail>::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL,
110 tile, _cur_railtype, track, _settings_client.gui.auto_remove_signals);
111 }
112}
113
122{
123 if (GetRailTileType(tile) == RailTileType::Depot) return;
124 if (GetRailTileType(tile) == RailTileType::Signals && !_settings_client.gui.auto_remove_signals) return;
125 if ((GetTrackBits(tile) & DiagdirReachesTracks(dir)) == 0) return;
126
127 Command<Commands::BuildRail>::Post(tile, _cur_railtype, track, _settings_client.gui.auto_remove_signals);
128}
129
131static const Track _place_depot_extra_track[12] = {
132 TRACK_LEFT, TRACK_UPPER, TRACK_UPPER, TRACK_RIGHT, // First additional track for directions 0..3
133 TRACK_X, TRACK_Y, TRACK_X, TRACK_Y, // Second additional track
134 TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT, TRACK_LOWER, // Third additional track
135};
136
143
144void CcRailDepot(Commands, const CommandCost &result, TileIndex tile, RailType, DiagDirection dir)
145{
146 if (result.Failed()) return;
147
148 if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile);
149 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
150
151 tile += TileOffsByDiagDir(dir);
152
153 if (IsTileType(tile, TileType::Railway)) {
155
156 /* Don't place the rail straight out of the depot of there is another depot across from it. */
157 Tile double_depot_tile = tile + TileOffsByDiagDir(dir);
158 bool is_double_depot = IsValidTile(double_depot_tile) && IsRailDepotTile(double_depot_tile);
159 if (!is_double_depot) PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir + 4], _place_depot_extra_track[dir + 4]);
160
162 }
163}
164
170{
173 return;
174 }
175
176 Axis axis = GetAxisForNewRailWaypoint(tile);
177 if (IsValidAxis(axis)) {
178 /* Valid tile for waypoints */
180 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
181 } else {
182 /* Tile where we can't build rail waypoints. This is always going to fail,
183 * but provides the user with a proper error message. */
184 Command<Commands::BuildRailWaypoint>::Post(STR_ERROR_CAN_T_BUILD_RAIL_WAYPOINT , tile, AXIS_X, 1, 1, STAT_CLASS_WAYP, 0, StationID::Invalid(), false);
185 }
186}
187
188void CcStation(Commands, const CommandCost &result, TileIndex tile)
189{
190 if (result.Failed()) return;
191
192 if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile);
193 /* Only close the station builder window if the default station and non persistent building is chosen. */
194 if (_station_gui.sel_class == STAT_CLASS_DFLT && _station_gui.sel_type == 0 && !_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
195}
196
202{
205 VpSetPlaceSizingLimit(-1);
206 } else if (_settings_client.gui.station_dragdrop) {
208 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
209 } else {
210 int w = _settings_client.gui.station_numtracks;
211 int h = _settings_client.gui.station_platlength;
212 if (!_station_gui.axis) std::swap(w, h);
213
216 uint8_t numtracks = _settings_client.gui.station_numtracks;
217 uint8_t platlength = _settings_client.gui.station_platlength;
218 bool adjacent = _ctrl_pressed;
219
220 auto proc = [=](bool test, StationID to_join) -> bool {
221 if (test) {
222 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();
223 } else {
224 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);
225 }
226 };
227
228 ShowSelectStationIfNeeded(TileArea(tile, w, h), proc);
229 }
230}
231
238{
240
241 if (trackbits & TRACK_BIT_VERT) { // N-S direction
242 trackbits = (_tile_fract_coords.x <= _tile_fract_coords.y) ? TRACK_BIT_RIGHT : TRACK_BIT_LEFT;
243 }
244
245 if (trackbits & TRACK_BIT_HORZ) { // E-W direction
246 trackbits = (_tile_fract_coords.x + _tile_fract_coords.y <= 15) ? TRACK_BIT_UPPER : TRACK_BIT_LOWER;
247 }
248
249 Track track = FindFirstTrack(trackbits);
250
252 Command<Commands::RemoveSignal>::Post(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM, CcPlaySound_CONSTRUCTION_RAIL, tile, track);
253 } else {
254 /* Which signals should we cycle through? */
255 bool tile_has_signal = IsPlainRailTile(tile) && IsValidTrack(track) && HasSignalOnTrack(tile, track);
256 SignalType cur_signal_on_tile = tile_has_signal ? GetSignalType(tile, track) : _cur_signal_type;
257 SignalType cycle_start;
258 SignalType cycle_end;
259
260 /* Start with the least restrictive case: the player wants to cycle through all signals they can see. */
261 if (_settings_client.gui.cycle_signal_types == SIGNAL_CYCLE_ALL) {
262 cycle_start = _settings_client.gui.signal_gui_mode == SIGNAL_GUI_ALL ? SIGTYPE_BLOCK : SIGTYPE_PBS;
263 cycle_end = SIGTYPE_LAST;
264 } else {
265 /* Only cycle through signals of the same group (block or path) as the current signal on the tile. */
266 if (cur_signal_on_tile <= SIGTYPE_LAST_NOPBS) {
267 /* Block signals only. */
268 cycle_start = SIGTYPE_BLOCK;
269 cycle_end = SIGTYPE_LAST_NOPBS;
270 } else {
271 /* Path signals only. */
272 cycle_start = SIGTYPE_PBS;
273 cycle_end = SIGTYPE_LAST;
274 }
275 }
276
277 if (FindWindowById(WC_BUILD_SIGNAL, 0) != nullptr) {
278 /* signal GUI is used */
279 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,
280 tile, track, _cur_signal_type, _cur_signal_variant, _convert_signal_button, false, _ctrl_pressed, cycle_start, cycle_end, 0, 0);
281 } else {
282 SignalVariant sigvar = TimerGameCalendar::year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC;
283 Command<Commands::BuildSignal>::Post(STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, CcPlaySound_CONSTRUCTION_RAIL,
284 tile, track, _settings_client.gui.default_signal_type, sigvar, false, false, _ctrl_pressed, cycle_start, cycle_end, 0, 0);
285
286 }
287 }
288}
289
295static void PlaceRail_Bridge(TileIndex tile, Window *w)
296{
297 if (IsBridgeTile(tile)) {
298 TileIndex other_tile = GetOtherTunnelBridgeEnd(tile);
299 Point pt = {0, 0};
300 w->OnPlaceMouseUp(VPM_X_OR_Y, DDSP_BUILD_BRIDGE, pt, other_tile, tile);
301 } else {
303 }
304}
305
308{
309 if (result.Succeeded()) {
310 if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile);
311 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
312 } else {
314 }
315}
316
329
336{
337 if (w->IsWidgetDisabled(WID_RAT_REMOVE)) return false;
338
339 /* allow ctrl to switch remove mode only for these widgets */
340 for (WidgetID i = WID_RAT_BUILD_NS; i <= WID_RAT_BUILD_STATION; i++) {
341 if ((i <= WID_RAT_AUTORAIL || i >= WID_RAT_BUILD_WAYPOINT) && w->IsWidgetLowered(i)) {
343 return true;
344 }
345 }
346
347 return false;
348}
349
350
357{
358 if (w->IsWidgetDisabled(WID_RAT_REMOVE)) return;
360 SndClickBeep();
361
362 /* handle station builder */
365 /* starting drag & drop remove */
366 if (!_settings_client.gui.station_dragdrop) {
367 SetTileSelectSize(1, 1);
368 } else {
369 VpSetPlaceSizingLimit(-1);
370 }
371 } else {
372 /* starting station build mode */
373 if (!_settings_client.gui.station_dragdrop) {
374 int x = _settings_client.gui.station_numtracks;
375 int y = _settings_client.gui.station_platlength;
376 if (_station_gui.axis == 0) std::swap(x, y);
377 SetTileSelectSize(x, y);
378 } else {
379 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
380 }
381 }
382 }
383}
384
385static void DoRailroadTrack(Track track)
386{
388 Command<Commands::RemoveRailLong>::Post(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL,
389 TileVirtXY(_thd.selend.x, _thd.selend.y), TileVirtXY(_thd.selstart.x, _thd.selstart.y), track);
390 } else {
391 Command<Commands::BuildRailLong>::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL,
392 TileVirtXY(_thd.selend.x, _thd.selend.y), TileVirtXY(_thd.selstart.x, _thd.selstart.y), _cur_railtype, track, _settings_client.gui.auto_remove_signals, false);
393 }
394}
395
396static void HandleAutodirPlacement()
397{
398 Track trackstat = static_cast<Track>( _thd.drawstyle & HT_DIR_MASK); // 0..5
399
400 if (_thd.drawstyle & HT_RAIL) { // one tile case
401 GenericPlaceRail(TileVirtXY(_thd.selend.x, _thd.selend.y), trackstat);
402 return;
403 }
404
405 DoRailroadTrack(trackstat);
406}
407
415{
416 Track track = (Track)GB(_thd.drawstyle, 0, 3); // 0..5
417
418 if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT) { // one tile case
419 GenericPlaceSignals(TileVirtXY(_thd.selend.x, _thd.selend.y));
420 return;
421 }
422
423 /* _settings_client.gui.drag_signals_density is given as a parameter such that each user
424 * in a network game can specify their own signal density */
426 Command<Commands::RemoveSignalLong>::Post(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM, CcPlaySound_CONSTRUCTION_RAIL,
427 TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), track, _ctrl_pressed);
428 } else {
429 bool sig_gui = FindWindowById(WC_BUILD_SIGNAL, 0) != nullptr;
430 SignalType sigtype = sig_gui ? _cur_signal_type : _settings_client.gui.default_signal_type;
431 SignalVariant sigvar = sig_gui ? _cur_signal_variant : (TimerGameCalendar::year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC);
432 Command<Commands::BuildSignalLong>::Post(STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, CcPlaySound_CONSTRUCTION_RAIL,
433 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);
434 }
435}
436
437
439struct BuildRailToolbarWindow : Window {
442
443 BuildRailToolbarWindow(WindowDesc &desc, RailType railtype) : Window(desc), railtype(railtype)
444 {
445 this->CreateNestedTree();
448 this->OnInvalidateData();
449
450 if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
451 }
452
453 void Close([[maybe_unused]] int data = 0) override
454 {
457 if (_settings_client.gui.link_terraform_toolbar) CloseWindowById(WC_SCEN_LAND_GEN, 0, false);
459 this->Window::Close();
460 }
461
468
469 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
470 {
471 if (!gui_scope) return;
472
473 if (!ValParamRailType(this->railtype)) {
474 /* Close toolbar if rail type is not available. */
475 this->Close();
476 return;
477 }
478
480 for (const WidgetID widget : can_build_widgets) this->SetWidgetDisabledState(widget, !can_build);
481 if (!can_build) {
487 }
488 }
489
490 bool OnTooltip([[maybe_unused]] Point pt, WidgetID widget, TooltipCloseCondition close_cond) override
491 {
493 if (can_build) return false;
494
495 if (std::ranges::find(can_build_widgets, widget) == std::end(can_build_widgets)) return false;
496
497 GuiShowTooltips(this, GetEncodedString(STR_TOOLBAR_DISABLED_NO_VEHICLE_AVAILABLE), close_cond);
498 return true;
499 }
500
501 void OnInit() override
502 {
503 /* Configure the rail toolbar for the railtype. */
504 const RailTypeInfo *rti = GetRailTypeInfo(this->railtype);
513 }
514
520 {
521 this->railtype = railtype;
522 this->ReInit();
523 }
524
525 void UpdateRemoveWidgetStatus(WidgetID clicked_widget)
526 {
527 switch (clicked_widget) {
528 case WID_RAT_REMOVE:
529 /* If it is the removal button that has been clicked, do nothing,
530 * as it is up to the other buttons to drive removal status */
531 return;
532
533 case WID_RAT_BUILD_NS:
534 case WID_RAT_BUILD_X:
535 case WID_RAT_BUILD_EW:
536 case WID_RAT_BUILD_Y:
537 case WID_RAT_AUTORAIL:
541 /* Removal button is enabled only if the rail/signal/waypoint/station
542 * button is still lowered. Once raised, it has to be disabled */
543 this->SetWidgetDisabledState(WID_RAT_REMOVE, !this->IsWidgetLowered(clicked_widget));
544 break;
545
546 default:
547 /* When any other buttons than rail/signal/waypoint/station, raise and
548 * disable the removal button */
551 break;
552 }
553 }
554
555 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
556 {
557 if (widget == WID_RAT_CAPTION) {
558 const RailTypeInfo *rti = GetRailTypeInfo(this->railtype);
559 if (rti->max_speed > 0) {
560 return GetString(STR_TOOLBAR_RAILTYPE_VELOCITY, rti->strings.toolbar_caption, PackVelocity(rti->max_speed, VEH_TRAIN));
561 }
562 return GetString(rti->strings.toolbar_caption);
563 }
564
565 return this->Window::GetWidgetString(widget, stringid);
566 }
567
574 {
575 switch (widget) {
583 case WID_RAT_BUILD_WAYPOINT: return SPR_CURSOR_WAYPOINT;
584 case WID_RAT_BUILD_STATION: return SPR_CURSOR_RAIL_STATION;
586 case WID_RAT_BUILD_BRIDGE: return SPR_CURSOR_BRIDGE;
589 default: NOT_REACHED();
590 }
591 }
592
599 {
600 switch (widget) {
601 case WID_RAT_BUILD_NS: return HT_LINE | HT_DIR_VL;
602 case WID_RAT_BUILD_X: return HT_LINE | HT_DIR_X;
603 case WID_RAT_BUILD_EW: return HT_LINE | HT_DIR_HL;
604 case WID_RAT_BUILD_Y: return HT_LINE | HT_DIR_Y;
605 case WID_RAT_AUTORAIL: return HT_RAIL;
606 case WID_RAT_DEMOLISH: return HT_RECT | HT_DIAGONAL;
607 case WID_RAT_BUILD_DEPOT: return HT_RECT;
608 case WID_RAT_BUILD_WAYPOINT: return HT_RECT;
609 case WID_RAT_BUILD_STATION: return HT_RECT;
610 case WID_RAT_BUILD_SIGNALS: return HT_RECT;
611 case WID_RAT_BUILD_BRIDGE: return HT_RECT;
612 case WID_RAT_BUILD_TUNNEL: return HT_SPECIAL;
614 default: NOT_REACHED();
615 }
616 }
617
618
619 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
620 {
621 if (widget < WID_RAT_BUILD_NS) return;
622
624
625 if (widget == WID_RAT_REMOVE) {
628 return;
629 }
630
631 this->last_user_action = widget;
632 bool started = HandlePlacePushButton(this, widget, this->GetCursorForWidget(widget), this->GetHighLightStyleForWidget(widget));
633
634 switch (widget) {
636 if (started) {
637 ShowBuildTrainDepotPicker(this);
638 }
639 break;
640
642 if (started) {
643 ShowBuildWaypointPicker(this);
644 }
645 break;
646
648 if (started) {
649 ShowStationBuilder(this);
650 }
651 break;
652
654 if (started != _ctrl_pressed) {
655 ShowSignalBuilder(this);
656 }
657 break;
658 }
659 }
660
661 this->UpdateRemoveWidgetStatus(widget);
663 }
664
665 EventState OnHotkey(int hotkey) override
666 {
667 if (IsSpecialHotkey(hotkey)) return this->ChangeRailTypeOnHotkey(hotkey);
668 MarkTileDirtyByTile(TileVirtXY(_thd.pos.x, _thd.pos.y)); // redraw tile selection
669 return Window::OnHotkey(hotkey);
670 }
671
672 void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override
673 {
674 switch (this->last_user_action) {
675 case WID_RAT_BUILD_NS:
677 break;
678
679 case WID_RAT_BUILD_X:
681 break;
682
683 case WID_RAT_BUILD_EW:
685 break;
686
687 case WID_RAT_BUILD_Y:
689 break;
690
691 case WID_RAT_AUTORAIL:
693 break;
694
695 case WID_RAT_DEMOLISH:
697 break;
698
700 Command<Commands::BuildRailDepot>::Post(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT, CcRailDepot, tile, _cur_railtype, _build_depot_direction);
701 break;
702
704 PlaceRail_Waypoint(tile);
705 break;
706
708 PlaceRail_Station(tile);
709 break;
710
713 break;
714
716 PlaceRail_Bridge(tile, this);
717 break;
718
720 Command<Commands::BuildTunnel>::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRailTunnel, tile, TRANSPORT_RAIL, _cur_railtype);
721 break;
722
725 break;
726
727 default: NOT_REACHED();
728 }
729 }
730
731 void OnPlaceDrag(ViewportPlaceMethod select_method, [[maybe_unused]] ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt) override
732 {
733 /* no dragging if you have pressed the convert button */
735
736 VpSelectTilesWithMethod(pt.x, pt.y, select_method);
737 }
738
739 Point OnInitialPosition(int16_t sm_width, [[maybe_unused]] int16_t sm_height, [[maybe_unused]] int window_number) override
740 {
741 return AlignInitialConstructionToolbar(sm_width);
742 }
743
744 void OnPlaceMouseUp([[maybe_unused]] ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt, TileIndex start_tile, TileIndex end_tile) override
745 {
746 if (pt.x != -1) {
747 switch (select_proc) {
748 default: NOT_REACHED();
750 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
751 ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_RAIL, _cur_railtype);
752 break;
753
754 case DDSP_PLACE_RAIL:
755 HandleAutodirPlacement();
756 break;
757
760 break;
761
763 GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
764 break;
765
767 Command<Commands::ConvertRail>::Post(STR_ERROR_CAN_T_CONVERT_RAIL, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _cur_railtype, _ctrl_pressed);
768 break;
769
773 /* Station */
775 bool keep_rail = !_ctrl_pressed;
776 Command<Commands::RemoveFromRailStation>::Post(STR_ERROR_CAN_T_REMOVE_PART_OF_STATION, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, keep_rail);
777 } else {
778 HandleStationPlacement(start_tile, end_tile);
779 }
780 } else {
781 /* Waypoint */
783 bool keep_rail = !_ctrl_pressed;
784 Command<Commands::RemoveFromRailWaypoint>::Post(STR_ERROR_CAN_T_REMOVE_RAIL_WAYPOINT , CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, keep_rail);
785 } else {
786 TileArea ta(start_tile, end_tile);
787 Axis axis = select_method == VPM_X_LIMITED ? AXIS_X : AXIS_Y;
788 bool adjacent = _ctrl_pressed;
789
790 auto proc = [=](bool test, StationID to_join) -> bool {
791 if (test) {
792 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();
793 } else {
794 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);
795 }
796 };
797
799 }
800 }
801 break;
802 }
803 }
804 }
805
822
823 void OnPlacePresize([[maybe_unused]] Point pt, TileIndex tile) override
824 {
825 Command<Commands::BuildTunnel>::Do(DoCommandFlag::Auto, tile, TRANSPORT_RAIL, _cur_railtype);
827 }
828
830 {
831 /* do not toggle Remove button by Ctrl when placing station */
833 return ES_NOT_HANDLED;
834 }
835
836 void OnRealtimeTick([[maybe_unused]] uint delta_ms) override
837 {
838 if (this->IsWidgetLowered(WID_RAT_BUILD_WAYPOINT)) CheckRedrawRailWaypointCoverage(this);
839 }
840
847 {
848 auto [index, step] = GetListIndexStep(SpecialListHotkeys(hotkey), _sorted_railtypes, this->railtype);
849
851 index = (index + step) % _sorted_railtypes.size();
852 }
853
856
857 /* Update cursor and all sub windows. */
858 if (_thd.GetCallbackWnd() == this) SetCursor(this->GetCursorForWidget(this->last_user_action), PAL_NONE);
860
861 return ES_HANDLED;
862 }
863
870 {
871 if (_game_mode != GM_NORMAL) return ES_NOT_HANDLED;
873 if (w == nullptr) return ES_NOT_HANDLED;
874 return w->OnHotkey(hotkey);
875 }
876
877 static inline HotkeyList hotkeys{"railtoolbar", {
878 Hotkey('1', "build_ns", WID_RAT_BUILD_NS),
879 Hotkey('2', "build_x", WID_RAT_BUILD_X),
880 Hotkey('3', "build_ew", WID_RAT_BUILD_EW),
881 Hotkey('4', "build_y", WID_RAT_BUILD_Y),
882 Hotkey({'5', 'A' | WKC_GLOBAL_HOTKEY}, "autorail", WID_RAT_AUTORAIL),
883 Hotkey('6', "demolish", WID_RAT_DEMOLISH),
884 Hotkey('7', "depot", WID_RAT_BUILD_DEPOT),
885 Hotkey('8', "waypoint", WID_RAT_BUILD_WAYPOINT),
886 Hotkey('9', "station", WID_RAT_BUILD_STATION),
887 Hotkey('S', "signal", WID_RAT_BUILD_SIGNALS),
888 Hotkey('B', "bridge", WID_RAT_BUILD_BRIDGE),
889 Hotkey('T', "tunnel", WID_RAT_BUILD_TUNNEL),
890 Hotkey('R', "remove", WID_RAT_REMOVE),
891 Hotkey('C', "convert", WID_RAT_CONVERT_RAIL),
894 Hotkey(WKC_L_BRACKET | WKC_CTRL, "first_railtype", to_underlying(SpecialListHotkeys::FirstItem)),
895 Hotkey(WKC_R_BRACKET | WKC_CTRL, "last_railtype", to_underlying(SpecialListHotkeys::LastItem)),
897};
898
899static constexpr std::initializer_list<NWidgetPart> _nested_build_rail_widgets = {
901 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
902 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_RAT_CAPTION), SetTextStyle(TC_WHITE),
903 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
904 EndContainer(),
906 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_BUILD_NS),
907 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_RAIL_NS, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
908 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_BUILD_X),
909 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_RAIL_NE, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
910 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_BUILD_EW),
911 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_RAIL_EW, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
912 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_BUILD_Y),
913 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_RAIL_NW, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
914 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_AUTORAIL),
915 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_AUTORAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL),
916
918
919 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_DEMOLISH),
920 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
921 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_BUILD_DEPOT),
922 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_DEPOT_RAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING),
923 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_BUILD_WAYPOINT),
924 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_WAYPOINT, STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT),
925 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_BUILD_STATION),
926 SetFill(0, 1), SetToolbarMinimalSize(2), SetSpriteTip(SPR_IMG_RAIL_STATION, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION),
927 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_BUILD_SIGNALS),
928 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_RAIL_SIGNALS, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS),
929 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_BUILD_BRIDGE),
930 SetFill(0, 1), SetToolbarMinimalSize(2), SetSpriteTip(SPR_IMG_BRIDGE, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE),
931 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_BUILD_TUNNEL),
932 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_TUNNEL_RAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL),
933 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_REMOVE),
934 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_REMOVE, STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR),
935 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_CONVERT_RAIL),
936 SetFill(0, 1), SetToolbarMinimalSize(1), SetSpriteTip(SPR_IMG_CONVERT_RAIL, STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL),
937 EndContainer(),
938};
939
940static WindowDesc _build_rail_desc(
941 WDP_MANUAL, "toolbar_rail", 0, 0,
944 _nested_build_rail_widgets,
945 &BuildRailToolbarWindow::hotkeys
946);
947
948
958{
959 if (!Company::IsValidID(_local_company)) return nullptr;
960 if (!ValParamRailType(railtype)) return nullptr;
961
963 _cur_railtype = railtype;
965 return new BuildRailToolbarWindow(_build_rail_desc, railtype);
966}
967
968/* TODO: For custom stations, respect their allowed platforms/lengths bitmasks!
969 * --pasky */
970
971static void HandleStationPlacement(TileIndex start, TileIndex end)
972{
973 TileArea ta(start, end);
974 uint numtracks = ta.w;
975 uint platlength = ta.h;
976
977 if (_station_gui.axis == AXIS_X) std::swap(numtracks, platlength);
978
981 bool adjacent = _ctrl_pressed;
982
983 auto proc = [=](bool test, StationID to_join) -> bool {
984 if (test) {
985 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();
986 } else {
987 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);
988 }
989 };
990
992}
993
999static bool StationUsesDefaultType(const BaseStation *bst)
1000{
1001 for (TileIndex t : bst->train_station) {
1002 if (bst->TileBelongsToRailStation(t) && HasStationRail(t) && GetCustomStationSpecIndex(t) == 0) return true;
1003 }
1004 return false;
1005}
1006
1007class StationPickerCallbacks : public PickerCallbacksNewGRFClass<StationClass> {
1008public:
1009 StationPickerCallbacks() : PickerCallbacksNewGRFClass<StationClass>("fav_stations") {}
1010
1011 GrfSpecFeature GetFeature() const override { return GSF_STATIONS; }
1012
1013 StringID GetClassTooltip() const override { return STR_PICKER_STATION_CLASS_TOOLTIP; }
1014 StringID GetTypeTooltip() const override { return STR_PICKER_STATION_TYPE_TOOLTIP; }
1015 StringID GetCollectionTooltip() const override { return STR_PICKER_STATION_COLLECTION_TOOLTIP; }
1016
1017 bool IsActive() const override
1018 {
1019 for (const auto &cls : StationClass::Classes()) {
1020 if (IsWaypointClass(cls)) continue;
1021 for (const auto *spec : cls.Specs()) {
1022 if (spec != nullptr) return true;
1023 }
1024 }
1025 return false;
1026 }
1027
1028 bool HasClassChoice() const override
1029 {
1030 return std::ranges::count_if(StationClass::Classes(), std::not_fn(IsWaypointClass)) > 1;
1031 }
1032
1033 int GetSelectedClass() const override { return _station_gui.sel_class; }
1034 void SetSelectedClass(int id) const override { _station_gui.sel_class = this->GetClassIndex(id); }
1035
1036 StringID GetClassName(int id) const override
1037 {
1038 const auto *sc = GetClass(id);
1039 if (IsWaypointClass(*sc)) return INVALID_STRING_ID;
1040 return sc->name;
1041 }
1042
1043 int GetSelectedType() const override { return _station_gui.sel_type; }
1044 void SetSelectedType(int id) const override { _station_gui.sel_type = id; }
1045
1046 StringID GetTypeName(int cls_id, int id) const override
1047 {
1048 const auto *spec = this->GetSpec(cls_id, id);
1049 return (spec == nullptr) ? STR_STATION_CLASS_DFLT_STATION : spec->name;
1050 }
1051
1052 std::span<const BadgeID> GetTypeBadges(int cls_id, int id) const override
1053 {
1054 const auto *spec = this->GetSpec(cls_id, id);
1055 if (spec == nullptr) return {};
1056 return spec->badges;
1057 }
1058
1059 bool IsTypeAvailable(int cls_id, int id) const override
1060 {
1061 return IsStationAvailable(this->GetSpec(cls_id, id));
1062 }
1063
1064 void DrawType(int x, int y, int cls_id, int id) const override
1065 {
1066 if (!DrawStationTile(x, y, _cur_railtype, _station_gui.axis, this->GetClassIndex(cls_id), id)) {
1067 StationPickerDrawSprite(x, y, StationType::Rail, _cur_railtype, INVALID_ROADTYPE, 2 + _station_gui.axis);
1068 }
1069 }
1070
1071 void FillUsedItems(std::set<PickerItem> &items) override
1072 {
1073 bool default_added = false;
1074 for (const Station *st : Station::Iterate()) {
1075 if (st->owner != _local_company) continue;
1076 if (!default_added && StationUsesDefaultType(st)) {
1077 items.insert({0, 0, STAT_CLASS_DFLT, 0});
1078 default_added = true;
1079 }
1080 for (const auto &sm : st->speclist) {
1081 if (sm.spec == nullptr) continue;
1082 items.insert({sm.grfid, sm.localidx, sm.spec->class_index, sm.spec->index});
1083 }
1084 }
1085 }
1086
1087 static StationPickerCallbacks instance;
1088};
1089/* static */ StationPickerCallbacks StationPickerCallbacks::instance;
1090
1091struct BuildRailStationWindow : public PickerWindow {
1092private:
1094
1100 void CheckSelectedSize(const StationSpec *statspec)
1101 {
1102 if (statspec == nullptr || _settings_client.gui.station_dragdrop) return;
1103
1104 /* If current number of tracks is not allowed, make it as big as possible */
1105 if (HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
1106 this->RaiseWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN);
1107 _settings_client.gui.station_numtracks = 1;
1108 if (statspec->disallowed_platforms != UINT8_MAX) {
1109 while (HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
1110 _settings_client.gui.station_numtracks++;
1111 }
1112 this->LowerWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN);
1113 }
1114 }
1115
1116 if (HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
1117 this->RaiseWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
1118 _settings_client.gui.station_platlength = 1;
1119 if (statspec->disallowed_lengths != UINT8_MAX) {
1120 while (HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
1121 _settings_client.gui.station_platlength++;
1122 }
1123 this->LowerWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
1124 }
1125 }
1126 }
1127
1128public:
1130 {
1131 this->coverage_height = 2 * GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal;
1132 this->ConstructWindow();
1133 }
1134
1135 void OnInit() override
1136 {
1138 if (_settings_client.gui.station_dragdrop) {
1140 } else {
1141 this->LowerWidget(WID_BRAS_PLATFORM_NUM_BEGIN + _settings_client.gui.station_numtracks);
1142 this->LowerWidget(WID_BRAS_PLATFORM_LEN_BEGIN + _settings_client.gui.station_platlength);
1143 }
1144 this->SetWidgetLoweredState(WID_BRAS_HIGHLIGHT_OFF, !_settings_client.gui.station_show_coverage);
1145 this->SetWidgetLoweredState(WID_BRAS_HIGHLIGHT_ON, _settings_client.gui.station_show_coverage);
1146
1147 this->PickerWindow::OnInit();
1148 }
1149
1150 void Close([[maybe_unused]] int data = 0) override
1151 {
1153 this->PickerWindow::Close();
1154 }
1155
1156 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
1157 {
1158 if (gui_scope) {
1159 const StationSpec *statspec = StationClass::Get(_station_gui.sel_class)->GetSpec(_station_gui.sel_type);
1160 this->CheckSelectedSize(statspec);
1161 }
1162
1163 this->PickerWindow::OnInvalidateData(data, gui_scope);
1164 }
1165
1166 void OnPaint() override
1167 {
1168 const StationSpec *statspec = StationClass::Get(_station_gui.sel_class)->GetSpec(_station_gui.sel_type);
1169
1170 if (_settings_client.gui.station_dragdrop) {
1171 SetTileSelectSize(1, 1);
1172 } else {
1173 int x = _settings_client.gui.station_numtracks;
1174 int y = _settings_client.gui.station_platlength;
1175 if (_station_gui.axis == AXIS_X) std::swap(x, y);
1177 SetTileSelectSize(x, y);
1178 }
1179 }
1180
1181 int rad = (_settings_game.station.modified_catchment) ? CA_TRAIN : CA_UNMODIFIED;
1182
1183 if (_settings_client.gui.station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
1184
1185 for (uint bits = 0; bits < 7; bits++) {
1186 bool disable = bits >= _settings_game.station.station_spread;
1187 if (statspec == nullptr) {
1188 this->SetWidgetDisabledState(bits + WID_BRAS_PLATFORM_NUM_1, disable);
1189 this->SetWidgetDisabledState(bits + WID_BRAS_PLATFORM_LEN_1, disable);
1190 } else {
1191 this->SetWidgetDisabledState(bits + WID_BRAS_PLATFORM_NUM_1, HasBit(statspec->disallowed_platforms, bits) || disable);
1192 this->SetWidgetDisabledState(bits + WID_BRAS_PLATFORM_LEN_1, HasBit(statspec->disallowed_lengths, bits) || disable);
1193 }
1194 }
1195
1196 this->DrawWidgets();
1197
1198 if (this->IsShaded()) return;
1199 /* 'Accepts' and 'Supplies' texts. */
1200 Rect r = this->GetWidget<NWidgetBase>(WID_BRAS_COVERAGE_TEXTS)->GetCurrentRect();
1201 const int bottom = r.bottom;
1202 r.bottom = INT_MAX; // Allow overflow as we want to know the required height.
1203 if (statspec != nullptr) r.top = DrawBadgeNameList(r, statspec->badges, GSF_STATIONS);
1204 r.top = DrawStationCoverageAreaText(r, SCT_ALL, rad, false) + WidgetDimensions::scaled.vsep_normal;
1205 r.top = DrawStationCoverageAreaText(r, SCT_ALL, rad, true);
1206 /* Resize background if the window is too small.
1207 * Never make the window smaller to avoid oscillating if the size change affects the acceptance.
1208 * (This is the case, if making the window bigger moves the mouse into the window.) */
1209 if (r.top > bottom) {
1210 this->coverage_height += r.top - bottom;
1211 this->ReInit();
1212 }
1213 }
1214
1215 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
1216 {
1217 switch (widget) {
1220 size.width = ScaleGUITrad(PREVIEW_WIDTH) + WidgetDimensions::scaled.fullbevel.Horizontal();
1221 size.height = ScaleGUITrad(PREVIEW_HEIGHT) + WidgetDimensions::scaled.fullbevel.Vertical();
1222 break;
1223
1225 size.height = this->coverage_height;
1226 break;
1227
1228 default:
1229 this->PickerWindow::UpdateWidgetSize(widget, size, padding, fill, resize);
1230 break;
1231 }
1232 }
1233
1234 void DrawWidget(const Rect &r, WidgetID widget) const override
1235 {
1236 DrawPixelInfo tmp_dpi;
1237
1238 switch (widget) {
1240 /* Set up a clipping area for the '/' station preview */
1241 Rect ir = r.Shrink(WidgetDimensions::scaled.bevel);
1242 if (FillDrawPixelInfo(&tmp_dpi, ir)) {
1243 AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
1246 if (!DrawStationTile(x, y, _cur_railtype, AXIS_X, _station_gui.sel_class, _station_gui.sel_type)) {
1247 StationPickerDrawSprite(x, y, StationType::Rail, _cur_railtype, INVALID_ROADTYPE, 2);
1248 }
1249 }
1250 break;
1251 }
1252
1254 /* Set up a clipping area for the '\' station preview */
1255 Rect ir = r.Shrink(WidgetDimensions::scaled.bevel);
1256 if (FillDrawPixelInfo(&tmp_dpi, ir)) {
1257 AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
1260 if (!DrawStationTile(x, y, _cur_railtype, AXIS_Y, _station_gui.sel_class, _station_gui.sel_type)) {
1261 StationPickerDrawSprite(x, y, StationType::Rail, _cur_railtype, INVALID_ROADTYPE, 3);
1262 }
1263 }
1264 break;
1265 }
1266
1267 default:
1268 this->PickerWindow::DrawWidget(r, widget);
1269 break;
1270 }
1271 }
1272
1273 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1274 {
1275 switch (widget) {
1279 _station_gui.axis = (Axis)(widget - WID_BRAS_PLATFORM_DIR_X);
1281 SndClickBeep();
1282 this->SetDirty();
1284 break;
1285
1293 this->RaiseWidget(WID_BRAS_PLATFORM_NUM_BEGIN + _settings_client.gui.station_numtracks);
1295
1296 _settings_client.gui.station_numtracks = widget - WID_BRAS_PLATFORM_NUM_BEGIN;
1297 _settings_client.gui.station_dragdrop = false;
1298
1299 const StationSpec *statspec = StationClass::Get(_station_gui.sel_class)->GetSpec(_station_gui.sel_type);
1300 if (statspec != nullptr && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
1301 /* The previously selected number of platforms in invalid */
1302 for (uint i = 0; i < 7; i++) {
1303 if (!HasBit(statspec->disallowed_lengths, i)) {
1304 this->RaiseWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
1305 _settings_client.gui.station_platlength = i + 1;
1306 break;
1307 }
1308 }
1309 }
1310
1311 this->LowerWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN);
1312 this->LowerWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
1313 SndClickBeep();
1314 this->SetDirty();
1316 break;
1317 }
1318
1326 this->RaiseWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
1328
1329 _settings_client.gui.station_platlength = widget - WID_BRAS_PLATFORM_LEN_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_platforms, _settings_client.gui.station_numtracks - 1)) {
1334 /* The previously selected number of tracks in invalid */
1335 for (uint i = 0; i < 7; i++) {
1336 if (!HasBit(statspec->disallowed_platforms, i)) {
1337 this->RaiseWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN);
1338 _settings_client.gui.station_numtracks = 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 SndClickBeep();
1347 this->SetDirty();
1349 break;
1350 }
1351
1353 _settings_client.gui.station_dragdrop ^= true;
1354
1356
1357 /* get the first allowed length/number of platforms */
1358 const StationSpec *statspec = StationClass::Get(_station_gui.sel_class)->GetSpec(_station_gui.sel_type);
1359 if (statspec != nullptr && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
1360 for (uint i = 0; i < 7; i++) {
1361 if (!HasBit(statspec->disallowed_lengths, i)) {
1362 this->RaiseWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
1363 _settings_client.gui.station_platlength = i + 1;
1364 break;
1365 }
1366 }
1367 }
1368 if (statspec != nullptr && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
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->SetWidgetLoweredState(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN, !_settings_client.gui.station_dragdrop);
1379 this->SetWidgetLoweredState(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN, !_settings_client.gui.station_dragdrop);
1380 SndClickBeep();
1381 this->SetDirty();
1383 break;
1384 }
1385
1388 _settings_client.gui.station_show_coverage = (widget != WID_BRAS_HIGHLIGHT_OFF);
1389
1390 this->SetWidgetLoweredState(WID_BRAS_HIGHLIGHT_OFF, !_settings_client.gui.station_show_coverage);
1391 this->SetWidgetLoweredState(WID_BRAS_HIGHLIGHT_ON, _settings_client.gui.station_show_coverage);
1392 SndClickBeep();
1393 this->SetDirty();
1394 SetViewportCatchmentStation(nullptr, true);
1395 break;
1396
1397 default:
1398 this->PickerWindow::OnClick(pt, widget, click_count);
1399 break;
1400 }
1401 }
1402
1403 void OnRealtimeTick([[maybe_unused]] uint delta_ms) override
1404 {
1406 }
1407
1414 {
1415 if (_game_mode == GM_MENU) return ES_NOT_HANDLED;
1417 if (w == nullptr) return ES_NOT_HANDLED;
1418 return w->OnHotkey(hotkey);
1419 }
1420
1421 static inline HotkeyList hotkeys{"buildrailstation", {
1422 Hotkey('F', "focus_filter_box", PCWHK_FOCUS_FILTER_BOX),
1424};
1425
1426static constexpr std::initializer_list<NWidgetPart> _nested_station_builder_widgets = {
1428 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1429 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_STATION_BUILD_RAIL_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1430 NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
1431 NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN),
1432 EndContainer(),
1436 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
1438 NWidget(WWT_LABEL, INVALID_COLOUR), SetMinimalSize(144, 11), SetFill(1, 0), SetStringTip(STR_STATION_BUILD_ORIENTATION),
1440 NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAS_PLATFORM_DIR_X), SetFill(0, 0), SetToolTip(STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(),
1441 NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAS_PLATFORM_DIR_Y), SetFill(0, 0), SetToolTip(STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(),
1442 EndContainer(),
1443 NWidget(WWT_LABEL, INVALID_COLOUR), SetMinimalSize(144, 11), SetFill(1, 0), SetStringTip(STR_STATION_BUILD_NUMBER_OF_TRACKS),
1445 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_NUM_1), SetAspect(1.25f), SetStringTip(STR_BLACK_1, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
1446 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_NUM_2), SetAspect(1.25f), SetStringTip(STR_BLACK_2, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
1447 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_NUM_3), SetAspect(1.25f), SetStringTip(STR_BLACK_3, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
1448 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_NUM_4), SetAspect(1.25f), SetStringTip(STR_BLACK_4, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
1449 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_NUM_5), SetAspect(1.25f), SetStringTip(STR_BLACK_5, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
1450 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_NUM_6), SetAspect(1.25f), SetStringTip(STR_BLACK_6, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
1451 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_NUM_7), SetAspect(1.25f), SetStringTip(STR_BLACK_7, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
1452 EndContainer(),
1453 NWidget(WWT_LABEL, INVALID_COLOUR), SetMinimalSize(144, 11), SetFill(1, 0), SetStringTip(STR_STATION_BUILD_PLATFORM_LENGTH),
1455 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_LEN_1), SetAspect(1.25f), SetStringTip(STR_BLACK_1, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
1456 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_LEN_2), SetAspect(1.25f), SetStringTip(STR_BLACK_2, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
1457 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_LEN_3), SetAspect(1.25f), SetStringTip(STR_BLACK_3, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
1458 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_LEN_4), SetAspect(1.25f), SetStringTip(STR_BLACK_4, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
1459 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_LEN_5), SetAspect(1.25f), SetStringTip(STR_BLACK_5, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
1460 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_LEN_6), SetAspect(1.25f), SetStringTip(STR_BLACK_6, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
1461 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_LEN_7), SetAspect(1.25f), SetStringTip(STR_BLACK_7, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
1462 EndContainer(),
1464 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_DRAG_N_DROP), SetMinimalSize(75, 12), SetStringTip(STR_STATION_BUILD_DRAG_DROP, STR_STATION_BUILD_DRAG_DROP_TOOLTIP),
1465 EndContainer(),
1466 NWidget(WWT_LABEL, INVALID_COLOUR), SetStringTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE), SetFill(1, 0),
1468 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_HIGHLIGHT_OFF), SetMinimalSize(60, 12), SetStringTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
1469 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_HIGHLIGHT_ON), SetMinimalSize(60, 12), SetStringTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
1470 EndContainer(),
1471 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BRAS_COVERAGE_TEXTS), SetFill(1, 1), SetResize(1, 0), SetMinimalTextLines(2, 0),
1472 EndContainer(),
1473 EndContainer(),
1474 EndContainer(),
1476 EndContainer(),
1477};
1478
1481 WDP_AUTO, "build_station_rail", 0, 0,
1484 _nested_station_builder_widgets,
1485 &BuildRailStationWindow::hotkeys
1486);
1487
1490{
1492}
1493
1494struct BuildSignalWindow : public PickerWindowBase {
1495private:
1498
1504 void DrawSignalSprite(const Rect &r, SpriteID image) const
1505 {
1506 Point offset;
1507 Dimension sprite_size = GetSpriteSize(image, &offset);
1508 Rect ir = r.Shrink(WidgetDimensions::scaled.imgbtn);
1509 int x = CentreBounds(ir.left, ir.right, sprite_size.width - offset.x) - offset.x; // centered
1510 int y = ir.top - sig_sprite_bottom_offset +
1511 (ir.Height() + sig_sprite_size.height) / 2; // aligned to bottom
1512
1513 DrawSprite(image, PAL_NONE, x, y);
1514 }
1515
1518 {
1519 bool show_non_path_signals = (_settings_client.gui.signal_gui_mode == SIGNAL_GUI_ALL);
1520
1521 this->GetWidget<NWidgetStacked>(WID_BS_BLOCK_SEL)->SetDisplayedPlane(show_non_path_signals ? 0 : SZSP_NONE);
1522 this->GetWidget<NWidgetStacked>(WID_BS_BLOCK_SPACER_SEL)->SetDisplayedPlane(show_non_path_signals ? 0 : SZSP_NONE);
1523 }
1524
1525public:
1527 {
1528 this->CreateNestedTree();
1529 this->SetSignalUIMode();
1531 this->OnInvalidateData();
1532 }
1533
1534 void Close([[maybe_unused]] int data = 0) override
1535 {
1536 _convert_signal_button = false;
1538 }
1539
1540 void OnInit() override
1541 {
1542 /* Calculate maximum signal sprite size. */
1543 this->sig_sprite_size.width = 0;
1544 this->sig_sprite_size.height = 0;
1545 this->sig_sprite_bottom_offset = 0;
1547 for (uint type = SIGTYPE_BLOCK; type < SIGTYPE_END; type++) {
1548 for (uint variant = SIG_ELECTRIC; variant <= SIG_SEMAPHORE; variant++) {
1549 for (uint lowered = 0; lowered < 2; lowered++) {
1550 Point offset;
1551 Dimension sprite_size = GetSpriteSize(rti->gui_sprites.signals[type][variant][lowered], &offset);
1552 this->sig_sprite_bottom_offset = std::max<int>(this->sig_sprite_bottom_offset, sprite_size.height);
1553 this->sig_sprite_size.width = std::max<int>(this->sig_sprite_size.width, sprite_size.width - offset.x);
1554 this->sig_sprite_size.height = std::max<int>(this->sig_sprite_size.height, sprite_size.height - offset.y);
1555 }
1556 }
1557 }
1558 }
1559
1560 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
1561 {
1562 if (widget == WID_BS_DRAG_SIGNALS_DENSITY_LABEL) {
1563 /* Two digits for signals density. */
1564 size.width = std::max(size.width, 2 * GetDigitWidth() + padding.width + WidgetDimensions::scaled.framerect.Horizontal());
1566 size.width = std::max(size.width, this->sig_sprite_size.width + padding.width);
1567 size.height = std::max(size.height, this->sig_sprite_size.height + padding.height);
1568 }
1569 }
1570
1571 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
1572 {
1573 switch (widget) {
1575 return GetString(STR_JUST_INT, _settings_client.gui.drag_signals_density);
1576
1577 default:
1578 return this->Window::GetWidgetString(widget, stringid);
1579 }
1580 }
1581
1582 void DrawWidget(const Rect &r, WidgetID widget) const override
1583 {
1585 /* Extract signal from widget number. */
1586 int type = (widget - WID_BS_SEMAPHORE_NORM) % SIGTYPE_END;
1587 int var = SIG_SEMAPHORE - (widget - WID_BS_SEMAPHORE_NORM) / SIGTYPE_END; // SignalVariant order is reversed compared to the widgets.
1588 SpriteID sprite = GetRailTypeInfo(_cur_railtype)->gui_sprites.signals[type][var][this->IsWidgetLowered(widget)];
1589
1590 this->DrawSignalSprite(r, sprite);
1591 }
1592 }
1593
1594 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1595 {
1596 switch (widget) {
1610
1611 _cur_signal_type = (SignalType)((uint)((widget - WID_BS_SEMAPHORE_NORM) % (SIGTYPE_LAST + 1)));
1613
1614 /* Update default (last-used) signal type in config file. */
1615 _settings_client.gui.default_signal_type = _cur_signal_type;
1616
1617 /* If 'remove' button of rail build toolbar is active, disable it. */
1620 if (w != nullptr) ToggleRailButton_Remove(w);
1621 }
1622
1623 SndClickBeep();
1624 break;
1625
1626 case WID_BS_CONVERT:
1628 SndClickBeep();
1629 break;
1630
1632 if (_settings_client.gui.drag_signals_density > 1) {
1633 _settings_client.gui.drag_signals_density--;
1635 }
1636 break;
1637
1639 if (_settings_client.gui.drag_signals_density < 20) {
1640 _settings_client.gui.drag_signals_density++;
1642 }
1643 break;
1644
1645 default: break;
1646 }
1647
1648 this->InvalidateData();
1649 }
1650
1656 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
1657 {
1658 if (!gui_scope) return;
1660
1662
1665 }
1666};
1667
1669static constexpr std::initializer_list<NWidgetPart> _nested_signal_builder_widgets = {
1670 /* Title bar and buttons. */
1672 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1673 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BS_CAPTION), SetStringTip(STR_BUILD_SIGNAL_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1674 EndContainer(),
1675
1676 /* Container for both signal groups, spacers, and convert/autofill buttons. */
1678 /* Block signals (can be hidden). */
1679 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BS_BLOCK_SEL),
1681 /* Semaphore block signals. */
1683 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_SEMAPHORE_NORM), SetToolTip(STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP), SetToolbarMinimalSize(1), EndContainer(),
1684 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_SEMAPHORE_ENTRY), SetToolTip(STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP), SetToolbarMinimalSize(1), EndContainer(),
1685 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_SEMAPHORE_EXIT), SetToolTip(STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP), SetToolbarMinimalSize(1), EndContainer(),
1686 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_SEMAPHORE_COMBO), SetToolTip(STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP), SetToolbarMinimalSize(1), EndContainer(),
1687 EndContainer(),
1688 /* Electric block signals. */
1690 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_ELECTRIC_NORM), SetToolTip(STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP), SetToolbarMinimalSize(1), EndContainer(),
1691 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_ELECTRIC_ENTRY), SetToolTip(STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TOOLTIP), SetToolbarMinimalSize(1), EndContainer(),
1692 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_ELECTRIC_EXIT), SetToolTip(STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP), SetToolbarMinimalSize(1), EndContainer(),
1693 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_ELECTRIC_COMBO), SetToolTip(STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP), SetToolbarMinimalSize(1), EndContainer(),
1694 EndContainer(),
1695 EndContainer(),
1696 EndContainer(),
1697
1698 /* Divider (only shown if block signals visible). */
1700 NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(0, 0), SetToolbarSpacerMinimalSize(), EndContainer(),
1701 EndContainer(),
1702
1703 /* Path signals. */
1705 /* Semaphore path signals. */
1707 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_SEMAPHORE_PBS), SetToolTip(STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP), SetToolbarMinimalSize(1), EndContainer(),
1708 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_SEMAPHORE_PBS_OWAY), SetToolTip(STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP), SetToolbarMinimalSize(1), EndContainer(),
1709 EndContainer(),
1710 /* Electric path signals. */
1712 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_ELECTRIC_PBS), SetToolTip(STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP), SetToolbarMinimalSize(1), EndContainer(),
1713 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_ELECTRIC_PBS_OWAY), SetToolTip(STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP), SetToolbarMinimalSize(1), EndContainer(),
1714 EndContainer(),
1715 EndContainer(),
1716
1717 /* Convert/autofill buttons. */
1719 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_BS_CONVERT), SetSpriteTip(SPR_IMG_SIGNAL_CONVERT, STR_BUILD_SIGNAL_CONVERT_TOOLTIP), SetFill(0, 1),
1720 NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetToolTip(STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(0, 1),
1722 NWidget(WWT_LABEL, INVALID_COLOUR, WID_BS_DRAG_SIGNALS_DENSITY_LABEL), SetToolTip(STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetTextStyle(TC_ORANGE), SetFill(1, 1),
1724 NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_BS_DRAG_SIGNALS_DENSITY_DECREASE), SetMinimalSize(9, 12), SetArrowWidgetTypeTip(AWV_DECREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP),
1725 NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_BS_DRAG_SIGNALS_DENSITY_INCREASE), SetMinimalSize(9, 12), SetArrowWidgetTypeTip(AWV_INCREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP),
1726 EndContainer(),
1727 EndContainer(),
1728 EndContainer(),
1729 EndContainer(),
1730 EndContainer(),
1731};
1732
1735 WDP_AUTO, {}, 0, 0,
1739);
1740
1744static void ShowSignalBuilder(Window *parent)
1745{
1747}
1748
1749struct BuildRailDepotWindow : public PickerWindowBase {
1750 BuildRailDepotWindow(WindowDesc &desc, Window *parent) : PickerWindowBase(desc, parent)
1751 {
1754 }
1755
1756 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
1757 {
1758 if (!IsInsideMM(widget, WID_BRAD_DEPOT_NE, WID_BRAD_DEPOT_NW + 1)) return;
1759
1760 size.width = ScaleGUITrad(64) + WidgetDimensions::scaled.fullbevel.Horizontal();
1761 size.height = ScaleGUITrad(48) + WidgetDimensions::scaled.fullbevel.Vertical();
1762 }
1763
1764 void DrawWidget(const Rect &r, WidgetID widget) const override
1765 {
1766 if (!IsInsideMM(widget, WID_BRAD_DEPOT_NE, WID_BRAD_DEPOT_NW + 1)) return;
1767
1768 DrawPixelInfo tmp_dpi;
1769 Rect ir = r.Shrink(WidgetDimensions::scaled.bevel);
1770 if (FillDrawPixelInfo(&tmp_dpi, ir)) {
1771 AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
1772 int x = (ir.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31);
1773 int y = (ir.Height() + ScaleSpriteTrad(48)) / 2 - ScaleSpriteTrad(31);
1774 DrawTrainDepotSprite(x, y, widget - WID_BRAD_DEPOT_NE + DIAGDIR_NE, _cur_railtype);
1775 }
1776 }
1777
1778 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1779 {
1780 switch (widget) {
1781 case WID_BRAD_DEPOT_NE:
1782 case WID_BRAD_DEPOT_SE:
1783 case WID_BRAD_DEPOT_SW:
1784 case WID_BRAD_DEPOT_NW:
1788 SndClickBeep();
1789 this->SetDirty();
1790 break;
1791 }
1792 }
1793};
1794
1796static constexpr std::initializer_list<NWidgetPart> _nested_build_depot_widgets = {
1798 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1799 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_BUILD_DEPOT_TRAIN_ORIENTATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1800 EndContainer(),
1801 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
1804 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAD_DEPOT_NW), SetToolTip(STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
1805 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAD_DEPOT_SW), SetToolTip(STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
1806 EndContainer(),
1808 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAD_DEPOT_NE), SetToolTip(STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
1809 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAD_DEPOT_SE), SetToolTip(STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
1810 EndContainer(),
1811 EndContainer(),
1812 EndContainer(),
1813};
1814
1815static WindowDesc _build_depot_desc(
1816 WDP_AUTO, {}, 0, 0,
1820);
1821
1822static void ShowBuildTrainDepotPicker(Window *parent)
1823{
1824 new BuildRailDepotWindow(_build_depot_desc, parent);
1825}
1826
1827class WaypointPickerCallbacks : public PickerCallbacksNewGRFClass<StationClass> {
1828public:
1829 WaypointPickerCallbacks() : PickerCallbacksNewGRFClass<StationClass>("fav_waypoints") {}
1830
1831 GrfSpecFeature GetFeature() const override { return GSF_STATIONS; }
1832
1833 StringID GetClassTooltip() const override { return STR_PICKER_WAYPOINT_CLASS_TOOLTIP; }
1834 StringID GetTypeTooltip() const override { return STR_PICKER_WAYPOINT_TYPE_TOOLTIP; }
1835 StringID GetCollectionTooltip() const override { return STR_PICKER_WAYPOINT_COLLECTION_TOOLTIP; }
1836
1837 bool IsActive() const override
1838 {
1839 for (const auto &cls : StationClass::Classes()) {
1840 if (!IsWaypointClass(cls)) continue;
1841 for (const auto *spec : cls.Specs()) {
1842 if (spec != nullptr) return true;
1843 }
1844 }
1845 return false;
1846 }
1847
1848 bool HasClassChoice() const override
1849 {
1850 return std::ranges::count_if(StationClass::Classes(), IsWaypointClass) > 1;
1851 }
1852
1853 void Close(int) override { ResetObjectToPlace(); }
1854 int GetSelectedClass() const override { return _waypoint_gui.sel_class; }
1855 void SetSelectedClass(int id) const override { _waypoint_gui.sel_class = this->GetClassIndex(id); }
1856
1857 StringID GetClassName(int id) const override
1858 {
1859 const auto *sc = GetClass(id);
1860 if (!IsWaypointClass(*sc)) return INVALID_STRING_ID;
1861 return sc->name;
1862 }
1863
1864 int GetSelectedType() const override { return _waypoint_gui.sel_type; }
1865 void SetSelectedType(int id) const override { _waypoint_gui.sel_type = id; }
1866
1867 StringID GetTypeName(int cls_id, int id) const override
1868 {
1869 const auto *spec = this->GetSpec(cls_id, id);
1870 return (spec == nullptr) ? STR_STATION_CLASS_WAYP_WAYPOINT : spec->name;
1871 }
1872
1873 std::span<const BadgeID> GetTypeBadges(int cls_id, int id) const override
1874 {
1875 const auto *spec = this->GetSpec(cls_id, id);
1876 if (spec == nullptr) return {};
1877 return spec->badges;
1878 }
1879
1880 bool IsTypeAvailable(int cls_id, int id) const override
1881 {
1882 return IsStationAvailable(this->GetSpec(cls_id, id));
1883 }
1884
1885 void DrawType(int x, int y, int cls_id, int id) const override
1886 {
1887 DrawWaypointSprite(x, y, this->GetClassIndex(cls_id), id, _cur_railtype);
1888 }
1889
1890 void FillUsedItems(std::set<PickerItem> &items) override
1891 {
1892 bool default_added = false;
1893 for (const Waypoint *wp : Waypoint::Iterate()) {
1894 if (wp->owner != _local_company || HasBit(wp->waypoint_flags, WPF_ROAD)) continue;
1895 if (!default_added && StationUsesDefaultType(wp)) {
1896 items.insert({0, 0, STAT_CLASS_WAYP, 0});
1897 default_added = true;
1898 }
1899 for (const auto &sm : wp->speclist) {
1900 if (sm.spec == nullptr) continue;
1901 items.insert({sm.grfid, sm.localidx, sm.spec->class_index, sm.spec->index});
1902 }
1903 }
1904 }
1905
1906 static WaypointPickerCallbacks instance;
1907};
1908/* static */ WaypointPickerCallbacks WaypointPickerCallbacks::instance;
1909
1910struct BuildRailWaypointWindow : public PickerWindow {
1911 BuildRailWaypointWindow(WindowDesc &desc, Window *parent) : PickerWindow(desc, parent, TRANSPORT_RAIL, WaypointPickerCallbacks::instance)
1912 {
1913 this->ConstructWindow();
1914 }
1915
1916 static inline HotkeyList hotkeys{"buildrailwaypoint", {
1917 Hotkey('F', "focus_filter_box", PCWHK_FOCUS_FILTER_BOX),
1918 }};
1919};
1920
1922static constexpr std::initializer_list<NWidgetPart> _nested_build_waypoint_widgets = {
1924 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1925 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_WAYPOINT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1926 NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
1927 NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN),
1928 EndContainer(),
1932 EndContainer(),
1933};
1934
1935static WindowDesc _build_waypoint_desc(
1936 WDP_AUTO, "build_waypoint", 0, 0,
1940 &BuildRailWaypointWindow::hotkeys
1941);
1942
1943static void ShowBuildWaypointPicker(Window *parent)
1944{
1945 if (!WaypointPickerCallbacks::instance.IsActive()) return;
1946 new BuildRailWaypointWindow(_build_waypoint_desc, parent);
1947}
1948
1960
1974
1977{
1979
1980 RailType rt;
1981 switch (_settings_client.gui.default_rail_type) {
1982 case 2: {
1983 /* Find the most used rail type */
1984 std::array<uint, RAILTYPE_END> count{};
1985 for (const auto t : Map::Iterate()) {
1988 count[GetRailType(t)]++;
1989 }
1990 }
1991
1992 rt = static_cast<RailType>(std::distance(std::begin(count), std::ranges::max_element(count)));
1993 if (count[rt] > 0) break;
1994
1995 /* No rail, just get the first available one */
1996 [[fallthrough]];
1997 }
1998 case 0: {
1999 /* Use first available type */
2000 std::vector<RailType>::const_iterator it = std::find_if(_sorted_railtypes.begin(), _sorted_railtypes.end(),
2001 [](RailType r) { return HasRailTypeAvail(_local_company, r); });
2002 rt = it != _sorted_railtypes.end() ? *it : RAILTYPE_BEGIN;
2003 break;
2004 }
2005 case 1: {
2006 /* Use last available type */
2007 std::vector<RailType>::const_reverse_iterator it = std::find_if(_sorted_railtypes.rbegin(), _sorted_railtypes.rend(),
2008 [](RailType r){ return HasRailTypeAvail(_local_company, r); });
2009 rt = it != _sorted_railtypes.rend() ? *it : RAILTYPE_BEGIN;
2010 break;
2011 }
2012 default:
2013 NOT_REACHED();
2014 }
2015
2018 if (w != nullptr) w->ModifyRailType(_cur_railtype);
2019}
2020
2026{
2027 SignalVariant new_variant = (TimerGameCalendar::year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC);
2028
2029 if (new_variant != _cur_signal_variant) {
2031 if (w != nullptr) {
2032 w->SetDirty();
2034 }
2035 _cur_signal_variant = new_variant;
2036 }
2037}
2038
2039static const IntervalTimer<TimerGameCalendar> _check_reset_signal({TimerGameCalendar::Trigger::Year, TimerGameCalendar::Priority::None}, [](auto)
2040{
2041 if (TimerGameCalendar::year != _settings_client.gui.semaphore_build_before) return;
2042
2044});
2045
2051{
2053
2054 _convert_signal_button = false;
2055 _cur_signal_type = _settings_client.gui.default_signal_type;
2057}
2058
2065DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option)
2066{
2067 RailTypes used_railtypes;
2068 RailTypes avail_railtypes;
2069
2071
2072 /* Find the used railtypes. */
2073 if (for_replacement) {
2074 avail_railtypes = GetCompanyRailTypes(c->index, false);
2075 used_railtypes = GetRailTypes(false);
2076 } else {
2077 avail_railtypes = c->avail_railtypes;
2078 used_railtypes = GetRailTypes(true);
2079 }
2080
2081 DropDownList list;
2082
2083 if (all_option) {
2084 list.push_back(MakeDropDownListStringItem(STR_REPLACE_ALL_RAILTYPE, INVALID_RAILTYPE));
2085 }
2086
2087 Dimension d = { 0, 0 };
2088 /* Get largest icon size, to ensure text is aligned on each menu item. */
2089 if (!for_replacement) {
2090 used_railtypes.Reset(_railtypes_hidden_mask);
2091 for (const auto &rt : _sorted_railtypes) {
2092 if (!used_railtypes.Test(rt)) continue;
2093 const RailTypeInfo *rti = GetRailTypeInfo(rt);
2095 }
2096 }
2097
2098 /* Shared list so that each item can take ownership. */
2099 auto badge_class_list = std::make_shared<GUIBadgeClasses>(GSF_RAILTYPES);
2100
2101 for (const auto &rt : _sorted_railtypes) {
2102 /* If it's not used ever, don't show it to the user. */
2103 if (!used_railtypes.Test(rt)) continue;
2104
2105 const RailTypeInfo *rti = GetRailTypeInfo(rt);
2106
2107 if (for_replacement) {
2108 list.push_back(MakeDropDownListBadgeItem(badge_class_list, rti->badges, GSF_RAILTYPES, rti->introduction_date, GetString(rti->strings.replace_text), rt, !avail_railtypes.Test(rt)));
2109 } else {
2110 std::string str = rti->max_speed > 0
2111 ? GetString(STR_TOOLBAR_RAILTYPE_VELOCITY, rti->strings.menu_text, rti->max_speed)
2112 : GetString(rti->strings.menu_text);
2113 list.push_back(MakeDropDownListBadgeIconItem(badge_class_list, rti->badges, GSF_RAILTYPES, rti->introduction_date, RailBuildCost(rt), d, rti->gui_sprites.build_x_rail, PAL_NONE, std::move(str), rt, !avail_railtypes.Test(rt)));
2114 }
2115 }
2116
2117 if (list.empty()) {
2118 /* Empty dropdowns are not allowed */
2119 list.push_back(MakeDropDownListStringItem(STR_NONE, INVALID_RAILTYPE, true));
2120 }
2121
2122 return list;
2123}
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, uint8_t road_rail_type)
Prepare the data for the build a bridge window.
bool IsBridgeTile(Tile t)
checks if there is a bridge on this tile
Definition bridge_map.h:35
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Timpl & Reset()
Reset all bits.
Common return value for all commands.
bool Succeeded() const
Did this command succeed?
bool Failed() const
Did this command fail?
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
static std::span< NewGRFClass< StationSpec, StationClassID, Tmax > const > Classes()
static NewGRFClass * Get(StationClassID class_index)
const Tspec * GetSpec(uint index) const
Get a spec from the class at a given index.
Base class for windows opened from a toolbar.
Definition window_gui.h:995
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
Definition window.cpp:3616
static constexpr int PREVIEW_WIDTH
Width of each preview button.
Definition picker_gui.h:219
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:220
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:221
static constexpr int PREVIEW_BOTTOM
Offset from bottom edge to draw preview.
Definition picker_gui.h:222
@ PCWHK_FOCUS_FILTER_BOX
Focus the edit box for editing the filter string.
Definition picker_gui.h:253
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:115
uint16_t max_speed
Maximum speed for vehicles travelling on this rail type.
Definition rail.h:220
SpriteID build_tunnel
button for building a tunnel
Definition rail.h:148
CursorID rail_swne
Cursor for building rail in X direction.
Definition rail.h:155
SpriteID convert_rail
button for converting rail
Definition rail.h:149
struct RailTypeInfo::@157247141350136173143103254227157213063052244122 strings
Strings associated with the rail type.
CursorID convert
Cursor for converting track.
Definition rail.h:161
CursorID depot
Cursor for building a depot.
Definition rail.h:159
TimerGameCalendar::Date introduction_date
Introduction date.
Definition rail.h:244
CursorID rail_nwse
Cursor for building rail in Y direction.
Definition rail.h:157
SpriteID build_x_rail
button for building single rail in X direction
Definition rail.h:143
CursorID rail_ew
Cursor for building rail in E-W direction.
Definition rail.h:156
SpriteID auto_rail
button for the autorail construction
Definition rail.h:146
CursorID autorail
Cursor for autorail tool.
Definition rail.h:158
StringID menu_text
Name of this rail type in the main toolbar dropdown.
Definition rail.h:167
StringID toolbar_caption
Caption in the construction toolbar GUI for this rail type.
Definition rail.h:166
struct RailTypeInfo::@047376261311064105134233254254216006075341230376 gui_sprites
struct containing the sprites for the rail GUI.
SpriteID signals[SIGTYPE_END][2][2]
signal GUI sprites (type, variant, state)
Definition rail.h:150
SpriteID build_ew_rail
button for building single rail in E-W direction
Definition rail.h:144
SpriteID build_y_rail
button for building single rail in Y direction
Definition rail.h:145
StringID replace_text
Text used in the autoreplace GUI.
Definition rail.h:169
SpriteID build_depot
button for building depots
Definition rail.h:147
SpriteID build_ns_rail
button for building single rail in N-S direction
Definition rail.h:142
CursorID rail_ns
Cursor for building rail in N-S direction.
Definition rail.h:154
SpriteID tunnel
tunnel sprites base
Definition rail.h:133
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 of a type.
StringID GetTypeName(int cls_id, int id) const override
Get the item of a type.
StringID GetClassTooltip() const override
Get the tooltip string for the class list.
void 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.
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.
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.
std::span< const BadgeID > GetTypeBadges(int cls_id, int id) const override
Get the item 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 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:93
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
Allow incrementing of DiagDirDiff variables.
@ AXIS_X
The X axis.
@ AXIS_Y
The y axis.
DiagDirection
Enumeration for diagonal directions.
@ DIAGDIR_NE
Northeast, upper right on your monitor.
@ DIAGDIR_NW
Northwest.
@ DIAGDIR_SE
Southeast.
@ DIAGDIR_SW
Southwest.
Functions related to the drop down widget.
Types related to the drop down widget.
std::vector< std::unique_ptr< const DropDownListItem > > DropDownList
A drop down list is a collection of drop down list items.
Base class for engines.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Definition enum_type.hpp:17
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:87
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:972
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:1738
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:1038
uint8_t GetDigitWidth(FontSize size)
Return the maximum width of single digit.
Definition gfx.cpp:1291
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:1573
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
@ FS_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
@ 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 SetTextStyle(TextColour colour, FontSize size=FS_NORMAL)
Widget part function for setting the text style.
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 SetArrowWidgetTypeTip(ArrowWidgetValues widget_type, StringID tip={})
Widget part function for setting the arrow widget type and tooltip.
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=INVALID_WIDGET)
Widget part function for starting a new 'real' widget.
constexpr NWidgetPart SetMinimalTextLines(uint8_t lines, uint8_t spacing, FontSize size=FS_NORMAL)
Widget part function for setting the minimal text lines.
constexpr NWidgetPart SetResize(int16_t dx, int16_t dy)
Widget part function for setting the resize step.
constexpr NWidgetPart SetPIPRatio(uint8_t ratio_pre, uint8_t ratio_inter, uint8_t ratio_post)
Widget part function for setting a pre/inter/post ratio.
void SetDirty() const
Mark entire window as dirty (in need of re-paint).
Definition window.cpp:969
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1554
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:100
SpecialListHotkeys
Indexes for special hotkeys to navigate in lists.
Definition hotkeys.h:83
@ NextItem
Hotkey to select next item in the list.
Definition hotkeys.h:85
@ FirstItem
Hotkey to select first item in the list.
Definition hotkeys.h:86
@ LastItem
Hotkey to select last item in the list.
Definition hotkeys.h:87
@ PreviousItem
Hotkey to select previous item in the list.
Definition hotkeys.h:84
bool IsSpecialHotkey(const int &hotkey)
Checks if hotkey index is special or not.
Definition hotkeys.h:74
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
#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:406
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:572
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:694
GrfSpecFeature
Definition newgrf.h:71
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.
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.
StationClassID
@ STAT_CLASS_DFLT
Default station class.
@ STAT_CLASS_WAYP
Waypoint class.
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:135
bool HasRailTypeAvail(const CompanyID company, const RailType railtype)
Finds out if a company has a certain buildable railtype available.
Definition rail.cpp:68
RailTypes GetRailTypes(bool introduces)
Get list of rail types, regardless of company availability.
Definition rail.cpp:166
bool ValParamRailType(const RailType rail)
Validate functions for rail building.
Definition rail.cpp:90
Money RailBuildCost(RailType railtype)
Returns the cost of building the specified railtype.
Definition rail.h:428
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:300
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:957
static bool RailToolbar_CtrlChanged(Window *w)
Updates the Remove button because of Ctrl state change.
Definition rail_gui.cpp:335
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:169
static void SetDefaultRailGui()
Set the initial (default) railtype to use.
static RailType _cur_railtype
Rail type of the current build-rail toolbar.
Definition rail_gui.cpp:57
static void HandleAutoSignalPlacement()
Build new signals or remove signals or (if only one tile marked) edit a signal.
Definition rail_gui.cpp:414
static SignalVariant _cur_signal_variant
set the signal variant (for signal GUI)
Definition rail_gui.cpp:61
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:121
static void PlaceRail_Bridge(TileIndex tile, Window *w)
Start placing a rail bridge.
Definition rail_gui.cpp:295
static void PlaceRail_Station(TileIndex tile)
Place a rail station.
Definition rail_gui.cpp:201
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:321
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:307
static WindowDesc _station_builder_desc(WDP_AUTO, "build_station_rail", 0, 0, WC_BUILD_STATION, WC_BUILD_TOOLBAR, WindowDefaultFlag::Construction, _nested_station_builder_widgets, &BuildRailStationWindow::hotkeys)
High level window description of the station-build window (default & newGRF).
static void BuildRailClick_Remove(Window *w)
The "remove"-button click proc of the build-rail toolbar.
Definition rail_gui.cpp:356
static WindowDesc _signal_builder_desc(WDP_AUTO, {}, 0, 0, WC_BUILD_SIGNAL, WC_BUILD_TOOLBAR, WindowDefaultFlag::Construction, _nested_signal_builder_widgets)
Signal selection window description.
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:88
static Window * ShowStationBuilder(Window *parent)
Open station build window.
static bool StationUsesDefaultType(const BaseStation *bst)
Test if a station/waypoint uses the default graphics.
Definition rail_gui.cpp:999
static const Track _place_depot_extra_track[12]
Additional pieces of track to add at the entrance of a depot.
Definition rail_gui.cpp:131
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 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.
static const DiagDirection _place_depot_extra_dir[12]
Direction to check for existing track pieces.
Definition rail_gui.cpp:138
void InitializeRailGUI()
Resets the rail GUI - sets default railtype to build and 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:237
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:25
@ SIGNAL_CYCLE_ALL
Cycle through all signals visible to the player.
Definition rail_gui.h:31
static RailTileType GetRailTileType(Tile t)
Returns the RailTileType (normal with or without signals, waypoint or depot).
Definition rail_map.h:36
RailType GetRailType(Tile t)
Gets the rail type of the given tile.
Definition rail_map.h:115
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:412
static bool IsRailDepotTile(Tile t)
Is this tile rail tile and a rail depot?
Definition rail_map.h:105
EnumBitSet< RailType, uint64_t > RailTypes
Allow incrementing of Track variables.
Definition rail_type.h:38
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
bool IsLevelCrossingTile(Tile t)
Return whether a tile is a level crossing tile.
Definition road_map.h:79
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:28
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
SignalType
Type of signal, i.e.
Definition signal_type.h:23
@ SIGTYPE_PBS
normal pbs signal
Definition signal_type.h:28
@ SIGTYPE_BLOCK
block signal
Definition signal_type.h:24
SignalVariant
Variant of the signal, i.e.
Definition signal_type.h:16
@ SIG_SEMAPHORE
Old-fashioned semaphore signal.
Definition signal_type.h:18
@ SIG_ELECTRIC
Light signal.
Definition signal_type.h:17
void SndClickBeep()
Play a beep sound for a click event if enabled in settings.
Definition sound.cpp:253
Functions related to sound.
@ SND_20_CONSTRUCTION_RAIL
30 == 0x1E Construction: rail infrastructure
Definition sound_type.h:78
static const CursorID ANIMCURSOR_BUILDSIGNALS
1292 - 1293 - build signal
Definition sprites.h:1526
static const CursorID ANIMCURSOR_DEMOLISH
704 - 707 - demolish dynamite
Definition sprites.h:1522
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.
bool HasStationTileRail(Tile t)
Has this station tile a rail?
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 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:439
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:823
RailType railtype
Rail type to build.
Definition rail_gui.cpp:440
void OnRealtimeTick(uint delta_ms) override
Called periodically.
Definition rail_gui.cpp:836
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition rail_gui.cpp:469
WidgetID last_user_action
Last started user action.
Definition rail_gui.cpp:441
void ModifyRailType(RailType railtype)
Switch to another rail type.
Definition rail_gui.cpp:519
void OnInit() override
Notification that the nested widget tree gets initialized.
Definition rail_gui.cpp:501
bool OnTooltip(Point pt, WidgetID widget, TooltipCloseCondition close_cond) override
Event to display a custom tooltip.
Definition rail_gui.cpp:490
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:619
EventState OnCTRLStateChange() override
The state of the control key has changed.
Definition rail_gui.cpp:829
CursorID GetCursorForWidget(WidgetID widget)
Returns corresponding cursor for provided button.
Definition rail_gui.cpp:573
EventState ChangeRailTypeOnHotkey(int hotkey)
Selects new RailType based on SpecialHotkeys and order defined in _sorted_railtypes.
Definition rail_gui.cpp:846
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
Definition rail_gui.cpp:555
void OnPlaceObjectAbort() override
The user cancelled a tile highlight mode that has been set.
Definition rail_gui.cpp:806
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:731
static EventState RailToolbarGlobalHotkeys(int hotkey)
Handler for global hotkeys of the BuildRailToolbarWindow.
Definition rail_gui.cpp:869
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:672
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:744
static const std::initializer_list< WidgetID > can_build_widgets
List of widgets to be disabled if infrastructure limit prevents building.
Definition rail_gui.cpp:463
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:739
EventState OnHotkey(int hotkey) override
A hotkey has been pressed.
Definition rail_gui.cpp:665
HighLightStyle GetHighLightStyleForWidget(WidgetID widget)
Returns corresponding high light style for provided button.
Definition rail_gui.cpp:598
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:453
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.
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:37
All data for a single hotkey.
Definition hotkeys.h:21
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
Definition map_func.h:365
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:168
Data structure for an opened window.
Definition window_gui.h:274
void ReInit(int rx=0, int ry=0, bool reposition=false)
Re-initialize a window, and optionally change its size.
Definition window.cpp:981
virtual void Close(int data=0)
Hide the window and all its child windows, and mark them for a later deletion.
Definition window.cpp:1106
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1812
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:766
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing).
Definition window.cpp:3250
Window * parent
Parent window.
Definition window_gui.h:329
void RaiseWidget(WidgetID widget_index)
Marks a widget as raised.
Definition window_gui.h:470
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:559
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
Definition window.cpp:507
ResizeInfo resize
Resize information.
Definition window_gui.h:315
void DisableWidget(WidgetID widget_index)
Sets a widget to disabled.
Definition window_gui.h:392
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1802
bool IsWidgetLowered(WidgetID widget_index) const
Gets the lowered state of a widget.
Definition window_gui.h:492
bool IsWidgetDisabled(WidgetID widget_index) const
Gets the enabled/disabled status of a widget.
Definition window_gui.h:411
void RaiseButtons(bool autoraise=false)
Raise the buttons of the window.
Definition window.cpp:533
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition window_gui.h:442
bool IsShaded() const
Is window shaded currently?
Definition window_gui.h:560
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:846
Window(WindowDesc &desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
Definition window.cpp:1835
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:986
void LowerWidget(WidgetID widget_index)
Marks a widget as lowered.
Definition window_gui.h:461
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition window.cpp:1825
virtual EventState OnHotkey(int hotkey)
A hotkey has been pressed.
Definition window.cpp:573
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:382
void ToggleWidgetLoweredState(WidgetID widget_index)
Invert the lowered/raised status of a widget.
Definition window_gui.h:451
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:303
bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_tile, TileIndex end_tile)
A central place to handle all X_AND_Y dragged GUI functions.
void PlaceProc_DemolishArea(TileIndex tile)
Start a drag for demolishing an area.
Window * ShowTerraformToolbar(Window *link)
Show the toolbar for terraforming in the game.
GUI stuff related to terraforming.
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
@ TunnelBridge
Tunnel entry/exit and bridge heads.
Definition tile_type.h:58
@ 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)
highlighting tiles while only going over them 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:28
Track FindFirstTrack(TrackBits tracks)
Returns first Track from TrackBits or INVALID_TRACK.
Definition track_func.h:177
TrackBits DiagdirReachesTracks(DiagDirection diagdir)
Returns all tracks that can be reached when entering a tile from a given (diagonal) direction.
Definition track_func.h:573
TrackBits TrackStatusToTrackBits(TrackStatus ts)
Returns the present-track-information of a TrackStatus.
Definition track_func.h:363
TrackBits
Allow incrementing of Track variables.
Definition track_type.h:35
@ TRACK_BIT_UPPER
Upper track.
Definition track_type.h:39
@ TRACK_BIT_LEFT
Left track.
Definition track_type.h:41
@ TRACK_BIT_HORZ
Upper and lower track.
Definition track_type.h:44
@ TRACK_BIT_LOWER
Lower track.
Definition track_type.h:40
@ TRACK_BIT_RIGHT
Right track.
Definition track_type.h:42
@ TRACK_BIT_VERT
Left and right track.
Definition track_type.h:45
Track
These are used to specify a single track.
Definition track_type.h:19
@ TRACK_Y
Track along the y-axis (north-west to south-east).
Definition track_type.h:22
@ TRACK_LOWER
Track in the lower corner of the tile (south).
Definition track_type.h:24
@ TRACK_LEFT
Track in the left corner of the tile (west).
Definition track_type.h:25
@ TRACK_RIGHT
Track in the right corner of the tile (east).
Definition track_type.h:26
@ TRACK_X
Track along the x-axis (north-east to south-west).
Definition track_type.h:21
@ TRACK_UPPER
Track in the upper corner of the tile (north).
Definition track_type.h:23
@ 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.
TransportType GetTunnelBridgeTransportType(Tile t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...
TileIndex GetOtherTunnelBridgeEnd(Tile t)
Determines type of the wormhole and returns its other end.
bool CanBuildVehicleInfrastructure(VehicleType type, uint8_t subtype)
Check whether we can build infrastructure for the given vehicle type.
Definition vehicle.cpp:1916
Functions related to vehicles.
@ VEH_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.
@ AWV_DECREASE
Arrow to the left or in case of RTL to the right.
Definition widget_type.h:20
@ AWV_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:1198
void CloseWindowByClass(WindowClass cls, int data)
Close all windows of a given class.
Definition window.cpp:1211
Point AlignInitialConstructionToolbar(int window_width)
Compute the position of the construction toolbars.
Definition window.cpp:1705
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition window.cpp:1155
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting).
Definition window.cpp:3188
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:153
@ WDP_AUTO
Find a place automatically.
Definition window_gui.h:144
@ WDP_MANUAL
Manually align the window (so no automatic location finding).
Definition window_gui.h:143
int WidgetID
Widget ID.
Definition window_type.h:20
@ WN_GAME_OPTIONS_GAME_SETTINGS
Game settings.
Definition window_type.h:32
EventState
State of handling an event.
@ ES_HANDLED
The passed event is handled.
@ ES_NOT_HANDLED
The passed event is not handled.
static constexpr WidgetID INVALID_WIDGET
An invalid widget index.
Definition window_type.h:23
@ WC_BUILD_STATION
Build station; Window numbers:
@ WC_BUILD_TOOLBAR
Build toolbar; Window numbers:
Definition window_type.h:78
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:50
@ WC_SCEN_LAND_GEN
Landscape generation (in Scenario Editor); Window numbers:
@ WC_SELECT_STATION
Select station (when joining stations); Window numbers:
@ WC_BUILD_SIGNAL
Build signal toolbar; Window numbers:
@ WC_BUILD_DEPOT
Build depot; Window numbers:
@ WC_GAME_OPTIONS
Game options window; Window numbers:
@ WC_BUILD_WAYPOINT
Build waypoint; Window numbers:
@ WC_BUILD_BRIDGE
Build bridge; Window numbers:
Functions related to zooming.
int ScaleSpriteTrad(int value)
Scale traditional pixel dimensions to GUI zoom level, for drawing sprites.
Definition zoom_func.h:107