2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8 /** @file road_gui.cpp GUI for building roads. */
12 #include "window_gui.h"
13 #include "station_gui.h"
14 #include "terraform_gui.h"
15 #include "viewport_func.h"
16 #include "command_func.h"
18 #include "station_func.h"
19 #include "window_func.h"
20 #include "vehicle_func.h"
21 #include "sound_func.h"
22 #include "company_func.h"
23 #include "tunnelbridge.h"
24 #include "tunnelbridge_map.h"
25 #include "tilehighlight_func.h"
26 #include "company_base.h"
29 #include "zoom_func.h"
30 #include "engine_base.h"
31 #include "strings_func.h"
32 #include "core/geometry_func.hpp"
33 #include "date_func.h"
34 #include "station_cmd.h"
36 #include "tunnelbridge_cmd.h"
38 #include "widgets/road_widget.h"
40 #include "table/strings.h"
42 #include "safeguards.h"
44 static void ShowRVStationPicker(Window
*parent
, RoadStopType rs
);
45 static void ShowRoadDepotPicker(Window
*parent
);
47 static bool _remove_button_clicked
;
48 static bool _one_way_button_clicked
;
50 static Axis _place_road_dir
;
51 static bool _place_road_start_half_x
;
52 static bool _place_road_start_half_y
;
53 static bool _place_road_end_half
;
55 static RoadType _cur_roadtype
;
57 static DiagDirection _road_depot_orientation
;
58 static DiagDirection _road_station_picker_orientation
;
60 void CcPlaySound_CONSTRUCTION_OTHER(Commands cmd
, const CommandCost
&result
, TileIndex tile
)
62 if (result
.Succeeded() && _settings_client
.sound
.confirm
) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER
, tile
);
66 * Callback to start placing a bridge.
67 * @param tile Start tile of the bridge.
69 static void PlaceRoad_Bridge(TileIndex tile
, Window
*w
)
71 if (IsBridgeTile(tile
)) {
72 TileIndex other_tile
= GetOtherTunnelBridgeEnd(tile
);
74 w
->OnPlaceMouseUp(VPM_X_OR_Y
, DDSP_BUILD_BRIDGE
, pt
, other_tile
, tile
);
76 VpStartPlaceSizing(tile
, VPM_X_OR_Y
, DDSP_BUILD_BRIDGE
);
81 * Callback executed after a build road tunnel command has been called.
84 * @param result Whether the build succeeded.
85 * @param start_tile Starting tile of the tunnel.
87 void CcBuildRoadTunnel(Commands cmd
, const CommandCost
&result
, TileIndex start_tile
)
89 if (result
.Succeeded()) {
90 if (_settings_client
.sound
.confirm
) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER
, start_tile
);
91 if (!_settings_client
.gui
.persistent_buildingtools
) ResetObjectToPlace();
93 DiagDirection start_direction
= ReverseDiagDir(GetTunnelBridgeDirection(start_tile
));
94 ConnectRoadToStructure(start_tile
, start_direction
);
96 TileIndex end_tile
= GetOtherTunnelBridgeEnd(start_tile
);
97 DiagDirection end_direction
= ReverseDiagDir(GetTunnelBridgeDirection(end_tile
));
98 ConnectRoadToStructure(end_tile
, end_direction
);
100 SetRedErrorSquare(_build_tunnel_endtile
);
105 * If required, connects a new structure to an existing road or tram by building the missing roadbit.
106 * @param tile Tile containing the structure to connect.
107 * @param direction Direction to check.
109 void ConnectRoadToStructure(TileIndex tile
, DiagDirection direction
)
111 tile
+= TileOffsByDiagDir(direction
);
112 /* if there is a roadpiece just outside of the station entrance, build a connecting route */
113 if (IsNormalRoadTile(tile
)) {
114 if (GetRoadBits(tile
, GetRoadTramType(_cur_roadtype
)) != ROAD_NONE
) {
115 Command
<CMD_BUILD_ROAD
>::Post(tile
, DiagDirToRoadBits(ReverseDiagDir(direction
)), _cur_roadtype
, DRD_NONE
, 0);
120 void CcRoadDepot(Commands cmd
, const CommandCost
&result
, TileIndex tile
, RoadType rt
, DiagDirection dir
)
122 if (result
.Failed()) return;
124 if (_settings_client
.sound
.confirm
) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER
, tile
);
125 if (!_settings_client
.gui
.persistent_buildingtools
) ResetObjectToPlace();
126 ConnectRoadToStructure(tile
, dir
);
130 * Command callback for building road stops.
132 * @param result Result of the build road stop command.
133 * @param tile Start tile.
134 * @param width Width of the road stop.
135 * @param length Length of the road stop.
136 * @param is_drive_through False for normal stops, true for drive-through.
137 * @param dir Entrance direction (#DiagDirection) for normal stops. Converted to the axis for drive-through stops.
138 * @see CmdBuildRoadStop
140 void CcRoadStop(Commands cmd
, const CommandCost
&result
, TileIndex tile
, uint8 width
, uint8 length
, RoadStopType
, bool is_drive_through
, DiagDirection dir
, RoadType
, StationID
, bool)
142 if (result
.Failed()) return;
144 if (_settings_client
.sound
.confirm
) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER
, tile
);
145 if (!_settings_client
.gui
.persistent_buildingtools
) ResetObjectToPlace();
146 TileArea
roadstop_area(tile
, width
, length
);
147 for (TileIndex cur_tile
: roadstop_area
) {
148 ConnectRoadToStructure(cur_tile
, dir
);
149 /* For a drive-through road stop build connecting road for other entrance. */
150 if (is_drive_through
) ConnectRoadToStructure(cur_tile
, ReverseDiagDir(dir
));
155 * Place a new road stop.
156 * @param start_tile First tile of the area.
157 * @param end_tile Last tile of the area.
158 * @param stop_type Type of stop (bus/truck).
159 * @param adjacent Allow stations directly adjacent to other stations.
160 * @param rt The roadtypes.
161 * @param err_msg Error message to show.
164 static void PlaceRoadStop(TileIndex start_tile
, TileIndex end_tile
, RoadStopType stop_type
, bool adjacent
, RoadType rt
, StringID err_msg
)
166 TileArea
ta(start_tile
, end_tile
);
167 DiagDirection ddir
= _road_station_picker_orientation
;
168 bool drive_through
= ddir
>= DIAGDIR_END
;
169 if (drive_through
) ddir
= static_cast<DiagDirection
>(ddir
- DIAGDIR_END
); // Adjust picker result to actual direction.
171 auto proc
= [=](bool test
, StationID to_join
) -> bool {
173 return Command
<CMD_BUILD_ROAD_STOP
>::Do(CommandFlagsToDCFlags(GetCommandFlags
<CMD_BUILD_ROAD_STOP
>()), ta
.tile
, ta
.w
, ta
.h
, stop_type
, drive_through
, ddir
, rt
, INVALID_STATION
, adjacent
).Succeeded();
175 return Command
<CMD_BUILD_ROAD_STOP
>::Post(err_msg
, CcRoadStop
, ta
.tile
, ta
.w
, ta
.h
, stop_type
, drive_through
, ddir
, rt
, to_join
, adjacent
);
179 ShowSelectStationIfNeeded(ta
, proc
);
183 * Callback for placing a bus station.
184 * @param tile Position to place the station.
186 static void PlaceRoad_BusStation(TileIndex tile
)
188 if (_remove_button_clicked
) {
189 VpStartPlaceSizing(tile
, VPM_X_AND_Y
, DDSP_REMOVE_BUSSTOP
);
191 if (_road_station_picker_orientation
< DIAGDIR_END
) { // Not a drive-through stop.
192 VpStartPlaceSizing(tile
, (DiagDirToAxis(_road_station_picker_orientation
) == AXIS_X
) ? VPM_X_LIMITED
: VPM_Y_LIMITED
, DDSP_BUILD_BUSSTOP
);
194 VpStartPlaceSizing(tile
, VPM_X_AND_Y_LIMITED
, DDSP_BUILD_BUSSTOP
);
196 VpSetPlaceSizingLimit(_settings_game
.station
.station_spread
);
201 * Callback for placing a truck station.
202 * @param tile Position to place the station.
204 static void PlaceRoad_TruckStation(TileIndex tile
)
206 if (_remove_button_clicked
) {
207 VpStartPlaceSizing(tile
, VPM_X_AND_Y
, DDSP_REMOVE_TRUCKSTOP
);
209 if (_road_station_picker_orientation
< DIAGDIR_END
) { // Not a drive-through stop.
210 VpStartPlaceSizing(tile
, (DiagDirToAxis(_road_station_picker_orientation
) == AXIS_X
) ? VPM_X_LIMITED
: VPM_Y_LIMITED
, DDSP_BUILD_TRUCKSTOP
);
212 VpStartPlaceSizing(tile
, VPM_X_AND_Y_LIMITED
, DDSP_BUILD_TRUCKSTOP
);
214 VpSetPlaceSizingLimit(_settings_game
.station
.station_spread
);
218 typedef void OnButtonClick(Window
*w
);
221 * Toggles state of the Remove button of Build road toolbar
222 * @param w window the button belongs to
224 static void ToggleRoadButton_Remove(Window
*w
)
226 w
->ToggleWidgetLoweredState(WID_ROT_REMOVE
);
227 w
->SetWidgetDirty(WID_ROT_REMOVE
);
228 _remove_button_clicked
= w
->IsWidgetLowered(WID_ROT_REMOVE
);
229 SetSelectionRed(_remove_button_clicked
);
233 * Updates the Remove button because of Ctrl state change
234 * @param w window the button belongs to
235 * @return true iff the remove button was changed
237 static bool RoadToolbar_CtrlChanged(Window
*w
)
239 if (w
->IsWidgetDisabled(WID_ROT_REMOVE
)) return false;
241 /* allow ctrl to switch remove mode only for these widgets */
242 for (uint i
= WID_ROT_ROAD_X
; i
<= WID_ROT_AUTOROAD
; i
++) {
243 if (w
->IsWidgetLowered(i
)) {
244 ToggleRoadButton_Remove(w
);
252 /** Road toolbar window handler. */
253 struct BuildRoadToolbarWindow
: Window
{
254 RoadType roadtype
; ///< Road type to build.
255 const RoadTypeInfo
*rti
; ///< Information about current road type
256 int last_started_action
; ///< Last started user action.
258 BuildRoadToolbarWindow(WindowDesc
*desc
, WindowNumber window_number
) : Window(desc
)
260 this->Initialize(_cur_roadtype
);
261 this->InitNested(window_number
);
262 this->SetupRoadToolbar();
263 this->SetWidgetDisabledState(WID_ROT_REMOVE
, true);
265 if (RoadTypeIsRoad(this->roadtype
)) {
266 this->SetWidgetDisabledState(WID_ROT_ONE_WAY
, true);
269 this->OnInvalidateData();
270 this->last_started_action
= WIDGET_LIST_END
;
272 if (_settings_client
.gui
.link_terraform_toolbar
) ShowTerraformToolbar(this);
275 void Close() override
277 if (_game_mode
== GM_NORMAL
&& (this->IsWidgetLowered(WID_ROT_BUS_STATION
) || this->IsWidgetLowered(WID_ROT_TRUCK_STATION
))) SetViewportCatchmentStation(nullptr, true);
278 if (_settings_client
.gui
.link_terraform_toolbar
) CloseWindowById(WC_SCEN_LAND_GEN
, 0, false);
279 this->Window::Close();
283 * Some data on this window has become invalid.
284 * @param data Information about the changed data.
285 * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
287 void OnInvalidateData(int data
= 0, bool gui_scope
= true) override
289 if (!gui_scope
) return;
290 RoadTramType rtt
= GetRoadTramType(this->roadtype
);
292 bool can_build
= CanBuildVehicleInfrastructure(VEH_ROAD
, rtt
);
293 this->SetWidgetsDisabledState(!can_build
,
296 WID_ROT_TRUCK_STATION
,
299 CloseWindowById(WC_BUS_STATION
, TRANSPORT_ROAD
);
300 CloseWindowById(WC_TRUCK_STATION
, TRANSPORT_ROAD
);
301 CloseWindowById(WC_BUILD_DEPOT
, TRANSPORT_ROAD
);
304 if (_game_mode
!= GM_EDITOR
) {
306 /* Show in the tooltip why this button is disabled. */
307 this->GetWidget
<NWidgetCore
>(WID_ROT_DEPOT
)->SetToolTip(STR_TOOLBAR_DISABLED_NO_VEHICLE_AVAILABLE
);
308 this->GetWidget
<NWidgetCore
>(WID_ROT_BUS_STATION
)->SetToolTip(STR_TOOLBAR_DISABLED_NO_VEHICLE_AVAILABLE
);
309 this->GetWidget
<NWidgetCore
>(WID_ROT_TRUCK_STATION
)->SetToolTip(STR_TOOLBAR_DISABLED_NO_VEHICLE_AVAILABLE
);
311 this->GetWidget
<NWidgetCore
>(WID_ROT_DEPOT
)->SetToolTip(rtt
== RTT_ROAD
? STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT
: STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT
);
312 this->GetWidget
<NWidgetCore
>(WID_ROT_BUS_STATION
)->SetToolTip(rtt
== RTT_ROAD
? STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION
: STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION
);
313 this->GetWidget
<NWidgetCore
>(WID_ROT_TRUCK_STATION
)->SetToolTip(rtt
== RTT_ROAD
? STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY
: STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION
);
318 void Initialize(RoadType roadtype
)
320 assert(roadtype
< ROADTYPE_END
);
321 this->roadtype
= roadtype
;
322 this->rti
= GetRoadTypeInfo(this->roadtype
);
326 * Configures the road toolbar for roadtype given
327 * @param roadtype the roadtype to display
329 void SetupRoadToolbar()
331 this->GetWidget
<NWidgetCore
>(WID_ROT_ROAD_X
)->widget_data
= rti
->gui_sprites
.build_x_road
;
332 this->GetWidget
<NWidgetCore
>(WID_ROT_ROAD_Y
)->widget_data
= rti
->gui_sprites
.build_y_road
;
333 this->GetWidget
<NWidgetCore
>(WID_ROT_AUTOROAD
)->widget_data
= rti
->gui_sprites
.auto_road
;
334 if (_game_mode
!= GM_EDITOR
) {
335 this->GetWidget
<NWidgetCore
>(WID_ROT_DEPOT
)->widget_data
= rti
->gui_sprites
.build_depot
;
337 this->GetWidget
<NWidgetCore
>(WID_ROT_CONVERT_ROAD
)->widget_data
= rti
->gui_sprites
.convert_road
;
338 this->GetWidget
<NWidgetCore
>(WID_ROT_BUILD_TUNNEL
)->widget_data
= rti
->gui_sprites
.build_tunnel
;
342 * Switch to another road type.
343 * @param roadtype New road type.
345 void ModifyRoadType(RoadType roadtype
)
347 this->Initialize(roadtype
);
348 this->SetupRoadToolbar();
352 void SetStringParameters(int widget
) const override
354 if (widget
== WID_ROT_CAPTION
) {
355 if (this->rti
->max_speed
> 0) {
356 SetDParam(0, STR_TOOLBAR_RAILTYPE_VELOCITY
);
357 SetDParam(1, this->rti
->strings
.toolbar_caption
);
358 SetDParam(2, this->rti
->max_speed
/ 2);
360 SetDParam(0, this->rti
->strings
.toolbar_caption
);
366 * Update the remove button lowered state of the road toolbar
368 * @param clicked_widget The widget which the client clicked just now
370 void UpdateOptionWidgetStatus(RoadToolbarWidgets clicked_widget
)
372 /* The remove and the one way button state is driven
373 * by the other buttons so they don't act on themselves.
374 * Both are only valid if they are able to apply as options. */
375 switch (clicked_widget
) {
377 if (RoadTypeIsRoad(this->roadtype
)) {
378 this->RaiseWidget(WID_ROT_ONE_WAY
);
379 this->SetWidgetDirty(WID_ROT_ONE_WAY
);
384 case WID_ROT_ONE_WAY
:
385 this->RaiseWidget(WID_ROT_REMOVE
);
386 this->SetWidgetDirty(WID_ROT_REMOVE
);
389 case WID_ROT_BUS_STATION
:
390 case WID_ROT_TRUCK_STATION
:
391 if (RoadTypeIsRoad(this->roadtype
)) this->DisableWidget(WID_ROT_ONE_WAY
);
392 this->SetWidgetDisabledState(WID_ROT_REMOVE
, !this->IsWidgetLowered(clicked_widget
));
397 case WID_ROT_AUTOROAD
:
398 this->SetWidgetDisabledState(WID_ROT_REMOVE
, !this->IsWidgetLowered(clicked_widget
));
399 if (RoadTypeIsRoad(this->roadtype
)) {
400 this->SetWidgetDisabledState(WID_ROT_ONE_WAY
, !this->IsWidgetLowered(clicked_widget
));
405 /* When any other buttons than road/station, raise and
406 * disable the removal button */
407 this->SetWidgetDisabledState(WID_ROT_REMOVE
, true);
408 this->SetWidgetLoweredState(WID_ROT_REMOVE
, false);
410 if (RoadTypeIsRoad(this->roadtype
)) {
411 this->SetWidgetDisabledState(WID_ROT_ONE_WAY
, true);
412 this->SetWidgetLoweredState(WID_ROT_ONE_WAY
, false);
419 void OnClick(Point pt
, int widget
, int click_count
) override
421 _remove_button_clicked
= false;
422 _one_way_button_clicked
= false;
425 HandlePlacePushButton(this, WID_ROT_ROAD_X
, this->rti
->cursor
.road_nwse
, HT_RECT
);
426 this->last_started_action
= widget
;
430 HandlePlacePushButton(this, WID_ROT_ROAD_Y
, this->rti
->cursor
.road_swne
, HT_RECT
);
431 this->last_started_action
= widget
;
434 case WID_ROT_AUTOROAD
:
435 HandlePlacePushButton(this, WID_ROT_AUTOROAD
, this->rti
->cursor
.autoroad
, HT_RECT
);
436 this->last_started_action
= widget
;
439 case WID_ROT_DEMOLISH
:
440 HandlePlacePushButton(this, WID_ROT_DEMOLISH
, ANIMCURSOR_DEMOLISH
, HT_RECT
| HT_DIAGONAL
);
441 this->last_started_action
= widget
;
445 if (HandlePlacePushButton(this, WID_ROT_DEPOT
, this->rti
->cursor
.depot
, HT_RECT
)) {
446 ShowRoadDepotPicker(this);
447 this->last_started_action
= widget
;
451 case WID_ROT_BUS_STATION
:
452 if (HandlePlacePushButton(this, WID_ROT_BUS_STATION
, SPR_CURSOR_BUS_STATION
, HT_RECT
)) {
453 ShowRVStationPicker(this, ROADSTOP_BUS
);
454 this->last_started_action
= widget
;
458 case WID_ROT_TRUCK_STATION
:
459 if (HandlePlacePushButton(this, WID_ROT_TRUCK_STATION
, SPR_CURSOR_TRUCK_STATION
, HT_RECT
)) {
460 ShowRVStationPicker(this, ROADSTOP_TRUCK
);
461 this->last_started_action
= widget
;
465 case WID_ROT_ONE_WAY
:
466 if (this->IsWidgetDisabled(WID_ROT_ONE_WAY
)) return;
468 this->ToggleWidgetLoweredState(WID_ROT_ONE_WAY
);
469 SetSelectionRed(false);
472 case WID_ROT_BUILD_BRIDGE
:
473 HandlePlacePushButton(this, WID_ROT_BUILD_BRIDGE
, SPR_CURSOR_BRIDGE
, HT_RECT
);
474 this->last_started_action
= widget
;
477 case WID_ROT_BUILD_TUNNEL
:
478 HandlePlacePushButton(this, WID_ROT_BUILD_TUNNEL
, this->rti
->cursor
.tunnel
, HT_SPECIAL
);
479 this->last_started_action
= widget
;
483 if (this->IsWidgetDisabled(WID_ROT_REMOVE
)) return;
485 CloseWindowById(WC_SELECT_STATION
, 0);
486 ToggleRoadButton_Remove(this);
487 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
490 case WID_ROT_CONVERT_ROAD
:
491 HandlePlacePushButton(this, WID_ROT_CONVERT_ROAD
, this->rti
->cursor
.convert_road
, HT_RECT
);
492 this->last_started_action
= widget
;
495 default: NOT_REACHED();
497 this->UpdateOptionWidgetStatus((RoadToolbarWidgets
)widget
);
498 if (_ctrl_pressed
) RoadToolbar_CtrlChanged(this);
501 EventState
OnHotkey(int hotkey
) override
503 MarkTileDirtyByTile(TileVirtXY(_thd
.pos
.x
, _thd
.pos
.y
)); // redraw tile selection
504 return Window::OnHotkey(hotkey
);
507 void OnPlaceObject(Point pt
, TileIndex tile
) override
509 _remove_button_clicked
= this->IsWidgetLowered(WID_ROT_REMOVE
);
510 _one_way_button_clicked
= RoadTypeIsRoad(this->roadtype
) ? this->IsWidgetLowered(WID_ROT_ONE_WAY
) : false;
511 switch (this->last_started_action
) {
513 _place_road_dir
= AXIS_X
;
514 _place_road_start_half_x
= _tile_fract_coords
.x
>= 8;
515 VpStartPlaceSizing(tile
, VPM_FIX_Y
, DDSP_PLACE_ROAD_X_DIR
);
519 _place_road_dir
= AXIS_Y
;
520 _place_road_start_half_y
= _tile_fract_coords
.y
>= 8;
521 VpStartPlaceSizing(tile
, VPM_FIX_X
, DDSP_PLACE_ROAD_Y_DIR
);
524 case WID_ROT_AUTOROAD
:
525 _place_road_dir
= INVALID_AXIS
;
526 _place_road_start_half_x
= _tile_fract_coords
.x
>= 8;
527 _place_road_start_half_y
= _tile_fract_coords
.y
>= 8;
528 VpStartPlaceSizing(tile
, VPM_X_OR_Y
, DDSP_PLACE_AUTOROAD
);
531 case WID_ROT_DEMOLISH
:
532 PlaceProc_DemolishArea(tile
);
536 Command
<CMD_BUILD_ROAD_DEPOT
>::Post(this->rti
->strings
.err_depot
, CcRoadDepot
,
537 tile
, _cur_roadtype
, _road_depot_orientation
);
540 case WID_ROT_BUS_STATION
:
541 PlaceRoad_BusStation(tile
);
544 case WID_ROT_TRUCK_STATION
:
545 PlaceRoad_TruckStation(tile
);
548 case WID_ROT_BUILD_BRIDGE
:
549 PlaceRoad_Bridge(tile
, this);
552 case WID_ROT_BUILD_TUNNEL
:
553 Command
<CMD_BUILD_TUNNEL
>::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE
, CcBuildRoadTunnel
,
554 tile
, TRANSPORT_ROAD
, _cur_roadtype
);
557 case WID_ROT_CONVERT_ROAD
:
558 VpStartPlaceSizing(tile
, VPM_X_AND_Y
, DDSP_CONVERT_ROAD
);
561 default: NOT_REACHED();
565 void OnPlaceObjectAbort() override
567 if (_game_mode
!= GM_EDITOR
&& (this->IsWidgetLowered(WID_ROT_BUS_STATION
) || this->IsWidgetLowered(WID_ROT_TRUCK_STATION
))) SetViewportCatchmentStation(nullptr, true);
569 this->RaiseButtons();
570 this->SetWidgetDisabledState(WID_ROT_REMOVE
, true);
571 this->SetWidgetDirty(WID_ROT_REMOVE
);
573 if (RoadTypeIsRoad(this->roadtype
)) {
574 this->SetWidgetDisabledState(WID_ROT_ONE_WAY
, true);
575 this->SetWidgetDirty(WID_ROT_ONE_WAY
);
578 CloseWindowById(WC_BUS_STATION
, TRANSPORT_ROAD
);
579 CloseWindowById(WC_TRUCK_STATION
, TRANSPORT_ROAD
);
580 CloseWindowById(WC_BUILD_DEPOT
, TRANSPORT_ROAD
);
581 CloseWindowById(WC_SELECT_STATION
, 0);
582 CloseWindowByClass(WC_BUILD_BRIDGE
);
585 void OnPlaceDrag(ViewportPlaceMethod select_method
, ViewportDragDropSelectionProcess select_proc
, Point pt
) override
587 /* Here we update the end tile flags
588 * of the road placement actions.
589 * At first we reset the end halfroad
590 * bits and if needed we set them again. */
591 switch (select_proc
) {
592 case DDSP_PLACE_ROAD_X_DIR
:
593 _place_road_end_half
= pt
.x
& 8;
596 case DDSP_PLACE_ROAD_Y_DIR
:
597 _place_road_end_half
= pt
.y
& 8;
600 case DDSP_PLACE_AUTOROAD
:
601 /* For autoroad we need to update the
602 * direction of the road */
603 if (_thd
.size
.x
> _thd
.size
.y
|| (_thd
.size
.x
== _thd
.size
.y
&&
604 ( (_tile_fract_coords
.x
< _tile_fract_coords
.y
&& (_tile_fract_coords
.x
+ _tile_fract_coords
.y
) < 16) ||
605 (_tile_fract_coords
.x
> _tile_fract_coords
.y
&& (_tile_fract_coords
.x
+ _tile_fract_coords
.y
) > 16) ))) {
607 _place_road_dir
= AXIS_X
;
608 _place_road_end_half
= pt
.x
& 8;
611 _place_road_dir
= AXIS_Y
;
612 _place_road_end_half
= pt
.y
& 8;
621 VpSelectTilesWithMethod(pt
.x
, pt
.y
, select_method
);
624 void OnPlaceMouseUp(ViewportPlaceMethod select_method
, ViewportDragDropSelectionProcess select_proc
, Point pt
, TileIndex start_tile
, TileIndex end_tile
) override
627 switch (select_proc
) {
628 default: NOT_REACHED();
629 case DDSP_BUILD_BRIDGE
:
630 if (!_settings_client
.gui
.persistent_buildingtools
) ResetObjectToPlace();
631 ShowBuildBridgeWindow(start_tile
, end_tile
, TRANSPORT_ROAD
, _cur_roadtype
);
634 case DDSP_DEMOLISH_AREA
:
635 GUIPlaceProcDragXY(select_proc
, start_tile
, end_tile
);
638 case DDSP_PLACE_ROAD_X_DIR
:
639 case DDSP_PLACE_ROAD_Y_DIR
:
640 case DDSP_PLACE_AUTOROAD
: {
641 bool start_half
= _place_road_dir
== AXIS_Y
? _place_road_start_half_y
: _place_road_start_half_x
;
643 if (_remove_button_clicked
) {
644 Command
<CMD_REMOVE_LONG_ROAD
>::Post(this->rti
->strings
.err_remove_road
, CcPlaySound_CONSTRUCTION_OTHER
,
645 end_tile
, start_tile
, _cur_roadtype
, _place_road_dir
, start_half
, _place_road_end_half
);
647 Command
<CMD_BUILD_LONG_ROAD
>::Post(this->rti
->strings
.err_build_road
, CcPlaySound_CONSTRUCTION_OTHER
,
648 end_tile
, start_tile
, _cur_roadtype
, _place_road_dir
, _one_way_button_clicked
? DRD_NORTHBOUND
: DRD_NONE
, start_half
, _place_road_end_half
, false);
653 case DDSP_BUILD_BUSSTOP
:
654 case DDSP_REMOVE_BUSSTOP
:
655 if (this->IsWidgetLowered(WID_ROT_BUS_STATION
)) {
656 if (_remove_button_clicked
) {
657 TileArea
ta(start_tile
, end_tile
);
658 Command
<CMD_REMOVE_ROAD_STOP
>::Post(this->rti
->strings
.err_remove_station
[ROADSTOP_BUS
], CcPlaySound_CONSTRUCTION_OTHER
, ta
.tile
, ta
.w
, ta
.h
, ROADSTOP_BUS
, _ctrl_pressed
);
660 PlaceRoadStop(start_tile
, end_tile
, ROADSTOP_BUS
, _ctrl_pressed
, _cur_roadtype
, this->rti
->strings
.err_build_station
[ROADSTOP_BUS
]);
665 case DDSP_BUILD_TRUCKSTOP
:
666 case DDSP_REMOVE_TRUCKSTOP
:
667 if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION
)) {
668 if (_remove_button_clicked
) {
669 TileArea
ta(start_tile
, end_tile
);
670 Command
<CMD_REMOVE_ROAD_STOP
>::Post(this->rti
->strings
.err_remove_station
[ROADSTOP_TRUCK
], CcPlaySound_CONSTRUCTION_OTHER
, ta
.tile
, ta
.w
, ta
.h
, ROADSTOP_TRUCK
, _ctrl_pressed
);
672 PlaceRoadStop(start_tile
, end_tile
, ROADSTOP_TRUCK
, _ctrl_pressed
, _cur_roadtype
, this->rti
->strings
.err_build_station
[ROADSTOP_TRUCK
]);
677 case DDSP_CONVERT_ROAD
:
678 Command
<CMD_CONVERT_ROAD
>::Post(rti
->strings
.err_convert_road
, CcPlaySound_CONSTRUCTION_OTHER
, end_tile
, start_tile
, _cur_roadtype
);
684 void OnPlacePresize(Point pt
, TileIndex tile
) override
686 Command
<CMD_BUILD_TUNNEL
>::Do(DC_AUTO
, tile
, TRANSPORT_ROAD
, _cur_roadtype
);
687 VpSetPresizeRange(tile
, _build_tunnel_endtile
== 0 ? tile
: _build_tunnel_endtile
);
690 EventState
OnCTRLStateChange() override
692 if (RoadToolbar_CtrlChanged(this)) return ES_HANDLED
;
693 return ES_NOT_HANDLED
;
696 static HotkeyList road_hotkeys
;
697 static HotkeyList tram_hotkeys
;
701 * Handler for global hotkeys of the BuildRoadToolbarWindow.
702 * @param hotkey Hotkey
703 * @param last_build Last build road type
704 * @return ES_HANDLED if hotkey was accepted.
706 static EventState
RoadTramToolbarGlobalHotkeys(int hotkey
, RoadType last_build
, RoadTramType rtt
)
709 switch (_game_mode
) {
711 w
= ShowBuildRoadToolbar(last_build
);
715 if ((GetRoadTypes(true) & ((rtt
== RTT_ROAD
) ? ~_roadtypes_type
: _roadtypes_type
)) == ROADTYPES_NONE
) return ES_NOT_HANDLED
;
716 w
= ShowBuildRoadScenToolbar(last_build
);
723 if (w
== nullptr) return ES_NOT_HANDLED
;
724 return w
->OnHotkey(hotkey
);
727 static EventState
RoadToolbarGlobalHotkeys(int hotkey
)
729 extern RoadType _last_built_roadtype
;
730 return RoadTramToolbarGlobalHotkeys(hotkey
, _last_built_roadtype
, RTT_ROAD
);
733 static EventState
TramToolbarGlobalHotkeys(int hotkey
)
735 extern RoadType _last_built_tramtype
;
736 return RoadTramToolbarGlobalHotkeys(hotkey
, _last_built_tramtype
, RTT_TRAM
);
739 static Hotkey roadtoolbar_hotkeys
[] = {
740 Hotkey('1', "build_x", WID_ROT_ROAD_X
),
741 Hotkey('2', "build_y", WID_ROT_ROAD_Y
),
742 Hotkey('3', "autoroad", WID_ROT_AUTOROAD
),
743 Hotkey('4', "demolish", WID_ROT_DEMOLISH
),
744 Hotkey('5', "depot", WID_ROT_DEPOT
),
745 Hotkey('6', "bus_station", WID_ROT_BUS_STATION
),
746 Hotkey('7', "truck_station", WID_ROT_TRUCK_STATION
),
747 Hotkey('8', "oneway", WID_ROT_ONE_WAY
),
748 Hotkey('B', "bridge", WID_ROT_BUILD_BRIDGE
),
749 Hotkey('T', "tunnel", WID_ROT_BUILD_TUNNEL
),
750 Hotkey('R', "remove", WID_ROT_REMOVE
),
751 Hotkey('C', "convert", WID_ROT_CONVERT_ROAD
),
754 HotkeyList
BuildRoadToolbarWindow::road_hotkeys("roadtoolbar", roadtoolbar_hotkeys
, RoadToolbarGlobalHotkeys
);
756 static Hotkey tramtoolbar_hotkeys
[] = {
757 Hotkey('1', "build_x", WID_ROT_ROAD_X
),
758 Hotkey('2', "build_y", WID_ROT_ROAD_Y
),
759 Hotkey('3', "autoroad", WID_ROT_AUTOROAD
),
760 Hotkey('4', "demolish", WID_ROT_DEMOLISH
),
761 Hotkey('5', "depot", WID_ROT_DEPOT
),
762 Hotkey('6', "bus_station", WID_ROT_BUS_STATION
),
763 Hotkey('7', "truck_station", WID_ROT_TRUCK_STATION
),
764 Hotkey('B', "bridge", WID_ROT_BUILD_BRIDGE
),
765 Hotkey('T', "tunnel", WID_ROT_BUILD_TUNNEL
),
766 Hotkey('R', "remove", WID_ROT_REMOVE
),
767 Hotkey('C', "convert", WID_ROT_CONVERT_ROAD
),
770 HotkeyList
BuildRoadToolbarWindow::tram_hotkeys("tramtoolbar", tramtoolbar_hotkeys
, TramToolbarGlobalHotkeys
);
773 static const NWidgetPart _nested_build_road_widgets
[] = {
774 NWidget(NWID_HORIZONTAL
),
775 NWidget(WWT_CLOSEBOX
, COLOUR_DARK_GREEN
),
776 NWidget(WWT_CAPTION
, COLOUR_DARK_GREEN
, WID_ROT_CAPTION
), SetDataTip(STR_WHITE_STRING
, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS
),
777 NWidget(WWT_STICKYBOX
, COLOUR_DARK_GREEN
),
779 NWidget(NWID_HORIZONTAL
),
780 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_ROAD_X
),
781 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_X_DIR
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION
),
782 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_ROAD_Y
),
783 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_Y_DIR
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION
),
784 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_AUTOROAD
),
785 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOROAD
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD
),
786 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_DEMOLISH
),
787 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE
, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC
),
788 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_DEPOT
),
789 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_DEPOT
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT
),
790 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_BUS_STATION
),
791 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_BUS_STATION
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION
),
792 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_TRUCK_STATION
),
793 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRUCK_BAY
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY
),
794 NWidget(WWT_PANEL
, COLOUR_DARK_GREEN
, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
795 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_ONE_WAY
),
796 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_ONE_WAY
, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD
),
797 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_BUILD_BRIDGE
),
798 SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE
),
799 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_BUILD_TUNNEL
),
800 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL
),
801 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_REMOVE
),
802 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE
, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD
),
803 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_CONVERT_ROAD
),
804 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_CONVERT_ROAD
, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD
),
808 static WindowDesc
_build_road_desc(
809 WDP_ALIGN_TOOLBAR
, "toolbar_road", 0, 0,
810 WC_BUILD_TOOLBAR
, WC_NONE
,
812 _nested_build_road_widgets
, lengthof(_nested_build_road_widgets
),
813 &BuildRoadToolbarWindow::road_hotkeys
816 static const NWidgetPart _nested_build_tramway_widgets
[] = {
817 NWidget(NWID_HORIZONTAL
),
818 NWidget(WWT_CLOSEBOX
, COLOUR_DARK_GREEN
),
819 NWidget(WWT_CAPTION
, COLOUR_DARK_GREEN
, WID_ROT_CAPTION
), SetDataTip(STR_WHITE_STRING
, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS
),
820 NWidget(WWT_STICKYBOX
, COLOUR_DARK_GREEN
),
822 NWidget(NWID_HORIZONTAL
),
823 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_ROAD_X
),
824 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRAMWAY_X_DIR
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION
),
825 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_ROAD_Y
),
826 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRAMWAY_Y_DIR
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION
),
827 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_AUTOROAD
),
828 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOTRAM
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM
),
829 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_DEMOLISH
),
830 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE
, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC
),
831 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_DEPOT
),
832 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_DEPOT
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT
),
833 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_BUS_STATION
),
834 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_BUS_STATION
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION
),
835 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_TRUCK_STATION
),
836 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRUCK_BAY
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION
),
837 NWidget(WWT_PANEL
, COLOUR_DARK_GREEN
, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
838 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_BUILD_BRIDGE
),
839 SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE
),
840 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_BUILD_TUNNEL
),
841 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL
),
842 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_REMOVE
),
843 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE
, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS
),
844 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_CONVERT_ROAD
),
845 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_CONVERT_ROAD
, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM
),
849 static WindowDesc
_build_tramway_desc(
850 WDP_ALIGN_TOOLBAR
, "toolbar_tramway", 0, 0,
851 WC_BUILD_TOOLBAR
, WC_NONE
,
853 _nested_build_tramway_widgets
, lengthof(_nested_build_tramway_widgets
),
854 &BuildRoadToolbarWindow::tram_hotkeys
858 * Open the build road toolbar window
860 * If the terraform toolbar is linked to the toolbar, that window is also opened.
862 * @return newly opened road toolbar, or nullptr if the toolbar could not be opened.
864 Window
*ShowBuildRoadToolbar(RoadType roadtype
)
866 if (!Company::IsValidID(_local_company
)) return nullptr;
867 if (!ValParamRoadType(roadtype
)) return nullptr;
869 CloseWindowByClass(WC_BUILD_TOOLBAR
);
870 _cur_roadtype
= roadtype
;
872 return AllocateWindowDescFront
<BuildRoadToolbarWindow
>(RoadTypeIsRoad(_cur_roadtype
) ? &_build_road_desc
: &_build_tramway_desc
, TRANSPORT_ROAD
);
875 static const NWidgetPart _nested_build_road_scen_widgets
[] = {
876 NWidget(NWID_HORIZONTAL
),
877 NWidget(WWT_CLOSEBOX
, COLOUR_DARK_GREEN
),
878 NWidget(WWT_CAPTION
, COLOUR_DARK_GREEN
, WID_ROT_CAPTION
), SetDataTip(STR_WHITE_STRING
, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS
),
879 NWidget(WWT_STICKYBOX
, COLOUR_DARK_GREEN
),
881 NWidget(NWID_HORIZONTAL
),
882 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_ROAD_X
),
883 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_X_DIR
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION
),
884 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_ROAD_Y
),
885 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_Y_DIR
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION
),
886 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_AUTOROAD
),
887 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOROAD
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD
),
888 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_DEMOLISH
),
889 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE
, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC
),
890 NWidget(WWT_PANEL
, COLOUR_DARK_GREEN
, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
891 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_ONE_WAY
),
892 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_ONE_WAY
, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD
),
893 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_BUILD_BRIDGE
),
894 SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE
),
895 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_BUILD_TUNNEL
),
896 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL
),
897 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_REMOVE
),
898 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE
, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD
),
899 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_CONVERT_ROAD
),
900 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_CONVERT_ROAD
, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD
),
904 static WindowDesc
_build_road_scen_desc(
905 WDP_AUTO
, "toolbar_road_scen", 0, 0,
906 WC_SCEN_BUILD_TOOLBAR
, WC_NONE
,
908 _nested_build_road_scen_widgets
, lengthof(_nested_build_road_scen_widgets
),
909 &BuildRoadToolbarWindow::road_hotkeys
912 static const NWidgetPart _nested_build_tramway_scen_widgets
[] = {
913 NWidget(NWID_HORIZONTAL
),
914 NWidget(WWT_CLOSEBOX
, COLOUR_DARK_GREEN
),
915 NWidget(WWT_CAPTION
, COLOUR_DARK_GREEN
, WID_ROT_CAPTION
), SetDataTip(STR_WHITE_STRING
, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS
),
916 NWidget(WWT_STICKYBOX
, COLOUR_DARK_GREEN
),
918 NWidget(NWID_HORIZONTAL
),
919 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_ROAD_X
),
920 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRAMWAY_X_DIR
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION
),
921 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_ROAD_Y
),
922 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRAMWAY_Y_DIR
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION
),
923 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_AUTOROAD
),
924 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOTRAM
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM
),
925 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_DEMOLISH
),
926 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE
, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC
),
927 NWidget(WWT_PANEL
, COLOUR_DARK_GREEN
, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
928 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_BUILD_BRIDGE
),
929 SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE
),
930 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_BUILD_TUNNEL
),
931 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL
, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL
),
932 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_REMOVE
),
933 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE
, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS
),
934 NWidget(WWT_IMGBTN
, COLOUR_DARK_GREEN
, WID_ROT_CONVERT_ROAD
),
935 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_CONVERT_ROAD
, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM
),
939 static WindowDesc
_build_tramway_scen_desc(
940 WDP_AUTO
, "toolbar_tram_scen", 0, 0,
941 WC_SCEN_BUILD_TOOLBAR
, WC_NONE
,
943 _nested_build_tramway_scen_widgets
, lengthof(_nested_build_tramway_scen_widgets
),
944 &BuildRoadToolbarWindow::tram_hotkeys
948 * Show the road building toolbar in the scenario editor.
949 * @return The just opened toolbar, or \c nullptr if the toolbar was already open.
951 Window
*ShowBuildRoadScenToolbar(RoadType roadtype
)
953 CloseWindowById(WC_SCEN_BUILD_TOOLBAR
, TRANSPORT_ROAD
);
954 _cur_roadtype
= roadtype
;
956 return AllocateWindowDescFront
<BuildRoadToolbarWindow
>(RoadTypeIsRoad(_cur_roadtype
) ? &_build_road_scen_desc
: &_build_tramway_scen_desc
, TRANSPORT_ROAD
);
959 struct BuildRoadDepotWindow
: public PickerWindowBase
{
960 BuildRoadDepotWindow(WindowDesc
*desc
, Window
*parent
) : PickerWindowBase(desc
, parent
)
962 this->CreateNestedTree();
964 this->LowerWidget(_road_depot_orientation
+ WID_BROD_DEPOT_NE
);
965 if (RoadTypeIsTram(_cur_roadtype
)) {
966 this->GetWidget
<NWidgetCore
>(WID_BROD_CAPTION
)->widget_data
= STR_BUILD_DEPOT_TRAM_ORIENTATION_CAPTION
;
967 for (int i
= WID_BROD_DEPOT_NE
; i
<= WID_BROD_DEPOT_NW
; i
++) this->GetWidget
<NWidgetCore
>(i
)->tool_tip
= STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP
;
970 this->FinishInitNested(TRANSPORT_ROAD
);
973 void UpdateWidgetSize(int widget
, Dimension
*size
, const Dimension
&padding
, Dimension
*fill
, Dimension
*resize
) override
975 if (!IsInsideMM(widget
, WID_BROD_DEPOT_NE
, WID_BROD_DEPOT_NW
+ 1)) return;
977 size
->width
= ScaleGUITrad(64) + 2;
978 size
->height
= ScaleGUITrad(48) + 2;
981 void DrawWidget(const Rect
&r
, int widget
) const override
983 if (!IsInsideMM(widget
, WID_BROD_DEPOT_NE
, WID_BROD_DEPOT_NW
+ 1)) return;
985 DrawRoadDepotSprite(r
.left
+ 1 + ScaleGUITrad(31), r
.bottom
- ScaleGUITrad(31), (DiagDirection
)(widget
- WID_BROD_DEPOT_NE
+ DIAGDIR_NE
), _cur_roadtype
);
988 void OnClick(Point pt
, int widget
, int click_count
) override
991 case WID_BROD_DEPOT_NW
:
992 case WID_BROD_DEPOT_NE
:
993 case WID_BROD_DEPOT_SW
:
994 case WID_BROD_DEPOT_SE
:
995 this->RaiseWidget(_road_depot_orientation
+ WID_BROD_DEPOT_NE
);
996 _road_depot_orientation
= (DiagDirection
)(widget
- WID_BROD_DEPOT_NE
);
997 this->LowerWidget(_road_depot_orientation
+ WID_BROD_DEPOT_NE
);
998 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
1008 static const NWidgetPart _nested_build_road_depot_widgets
[] = {
1009 NWidget(NWID_HORIZONTAL
),
1010 NWidget(WWT_CLOSEBOX
, COLOUR_DARK_GREEN
),
1011 NWidget(WWT_CAPTION
, COLOUR_DARK_GREEN
, WID_BROD_CAPTION
), SetDataTip(STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION
, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS
),
1013 NWidget(WWT_PANEL
, COLOUR_DARK_GREEN
),
1014 NWidget(NWID_SPACER
), SetMinimalSize(0, 3),
1015 NWidget(NWID_HORIZONTAL_LTR
),
1016 NWidget(NWID_SPACER
), SetMinimalSize(3, 0), SetFill(1, 0),
1017 NWidget(NWID_VERTICAL
),
1018 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BROD_DEPOT_NW
), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP
),
1020 NWidget(NWID_SPACER
), SetMinimalSize(0, 2),
1021 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BROD_DEPOT_SW
), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP
),
1024 NWidget(NWID_SPACER
), SetMinimalSize(2, 0),
1025 NWidget(NWID_VERTICAL
),
1026 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BROD_DEPOT_NE
), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP
),
1028 NWidget(NWID_SPACER
), SetMinimalSize(0, 2),
1029 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BROD_DEPOT_SE
), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP
),
1032 NWidget(NWID_SPACER
), SetMinimalSize(3, 0), SetFill(1, 0),
1034 NWidget(NWID_SPACER
), SetMinimalSize(0, 3),
1038 static WindowDesc
_build_road_depot_desc(
1039 WDP_AUTO
, nullptr, 0, 0,
1040 WC_BUILD_DEPOT
, WC_BUILD_TOOLBAR
,
1042 _nested_build_road_depot_widgets
, lengthof(_nested_build_road_depot_widgets
)
1045 static void ShowRoadDepotPicker(Window
*parent
)
1047 new BuildRoadDepotWindow(&_build_road_depot_desc
, parent
);
1050 struct BuildRoadStationWindow
: public PickerWindowBase
{
1051 BuildRoadStationWindow(WindowDesc
*desc
, Window
*parent
, RoadStopType rs
) : PickerWindowBase(desc
, parent
)
1053 this->CreateNestedTree();
1055 /* Trams don't have non-drivethrough stations */
1056 if (RoadTypeIsTram(_cur_roadtype
) && _road_station_picker_orientation
< DIAGDIR_END
) {
1057 _road_station_picker_orientation
= DIAGDIR_END
;
1059 const RoadTypeInfo
*rti
= GetRoadTypeInfo(_cur_roadtype
);
1060 this->GetWidget
<NWidgetCore
>(WID_BROS_CAPTION
)->widget_data
= rti
->strings
.picker_title
[rs
];
1062 for (uint i
= RoadTypeIsTram(_cur_roadtype
) ? WID_BROS_STATION_X
: WID_BROS_STATION_NE
; i
< WID_BROS_LT_OFF
; i
++) {
1063 this->GetWidget
<NWidgetCore
>(i
)->tool_tip
= rti
->strings
.picker_tooltip
[rs
];
1066 this->LowerWidget(_road_station_picker_orientation
+ WID_BROS_STATION_NE
);
1067 this->LowerWidget(_settings_client
.gui
.station_show_coverage
+ WID_BROS_LT_OFF
);
1069 this->FinishInitNested(TRANSPORT_ROAD
);
1071 this->window_class
= (rs
== ROADSTOP_BUS
) ? WC_BUS_STATION
: WC_TRUCK_STATION
;
1074 void Close() override
1076 CloseWindowById(WC_SELECT_STATION
, 0);
1077 this->PickerWindowBase::Close();
1080 void OnPaint() override
1082 this->DrawWidgets();
1084 int rad
= _settings_game
.station
.modified_catchment
? ((this->window_class
== WC_BUS_STATION
) ? CA_BUS
: CA_TRUCK
) : CA_UNMODIFIED
;
1085 if (_settings_client
.gui
.station_show_coverage
) {
1086 SetTileSelectBigSize(-rad
, -rad
, 2 * rad
, 2 * rad
);
1088 SetTileSelectSize(1, 1);
1091 /* 'Accepts' and 'Supplies' texts. */
1092 StationCoverageType sct
= (this->window_class
== WC_BUS_STATION
) ? SCT_PASSENGERS_ONLY
: SCT_NON_PASSENGERS_ONLY
;
1093 Rect r
= this->GetWidget
<NWidgetBase
>(WID_BROS_ACCEPTANCE
)->GetCurrentRect();
1094 int top
= r
.top
+ ScaleGUITrad(WD_PAR_VSEP_NORMAL
);
1095 top
= DrawStationCoverageAreaText(r
.left
, r
.right
, top
, sct
, rad
, false) + ScaleGUITrad(WD_PAR_VSEP_NORMAL
);
1096 top
= DrawStationCoverageAreaText(r
.left
, r
.right
, top
, sct
, rad
, true) + ScaleGUITrad(WD_PAR_VSEP_NORMAL
);
1097 /* Resize background if the window is too small.
1098 * Never make the window smaller to avoid oscillating if the size change affects the acceptance.
1099 * (This is the case, if making the window bigger moves the mouse into the window.) */
1100 if (top
> r
.bottom
) {
1101 ResizeWindow(this, 0, top
- r
.bottom
, false);
1105 void UpdateWidgetSize(int widget
, Dimension
*size
, const Dimension
&padding
, Dimension
*fill
, Dimension
*resize
) override
1107 if (!IsInsideMM(widget
, WID_BROS_STATION_NE
, WID_BROS_STATION_Y
+ 1)) return;
1109 size
->width
= ScaleGUITrad(64) + 2;
1110 size
->height
= ScaleGUITrad(48) + 2;
1113 void DrawWidget(const Rect
&r
, int widget
) const override
1115 if (!IsInsideMM(widget
, WID_BROS_STATION_NE
, WID_BROS_STATION_Y
+ 1)) return;
1117 StationType st
= (this->window_class
== WC_BUS_STATION
) ? STATION_BUS
: STATION_TRUCK
;
1118 StationPickerDrawSprite(r
.left
+ 1 + ScaleGUITrad(31), r
.bottom
- ScaleGUITrad(31), st
, INVALID_RAILTYPE
, _cur_roadtype
, widget
- WID_BROS_STATION_NE
);
1121 void OnClick(Point pt
, int widget
, int click_count
) override
1124 case WID_BROS_STATION_NE
:
1125 case WID_BROS_STATION_SE
:
1126 case WID_BROS_STATION_SW
:
1127 case WID_BROS_STATION_NW
:
1128 case WID_BROS_STATION_X
:
1129 case WID_BROS_STATION_Y
:
1130 this->RaiseWidget(_road_station_picker_orientation
+ WID_BROS_STATION_NE
);
1131 _road_station_picker_orientation
= (DiagDirection
)(widget
- WID_BROS_STATION_NE
);
1132 this->LowerWidget(_road_station_picker_orientation
+ WID_BROS_STATION_NE
);
1133 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
1135 CloseWindowById(WC_SELECT_STATION
, 0);
1138 case WID_BROS_LT_OFF
:
1139 case WID_BROS_LT_ON
:
1140 this->RaiseWidget(_settings_client
.gui
.station_show_coverage
+ WID_BROS_LT_OFF
);
1141 _settings_client
.gui
.station_show_coverage
= (widget
!= WID_BROS_LT_OFF
);
1142 this->LowerWidget(_settings_client
.gui
.station_show_coverage
+ WID_BROS_LT_OFF
);
1143 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
1145 SetViewportCatchmentStation(nullptr, true);
1153 void OnRealtimeTick(uint delta_ms
) override
1155 CheckRedrawStationCoverage(this);
1159 /** Widget definition of the build road station window */
1160 static const NWidgetPart _nested_road_station_picker_widgets
[] = {
1161 NWidget(NWID_HORIZONTAL
),
1162 NWidget(WWT_CLOSEBOX
, COLOUR_DARK_GREEN
),
1163 NWidget(WWT_CAPTION
, COLOUR_DARK_GREEN
, WID_BROS_CAPTION
),
1165 NWidget(WWT_PANEL
, COLOUR_DARK_GREEN
, WID_BROS_BACKGROUND
),
1166 NWidget(NWID_SPACER
), SetMinimalSize(0, 3),
1167 NWidget(NWID_HORIZONTAL
), SetPIP(0, 2, 0),
1168 NWidget(NWID_SPACER
), SetFill(1, 0),
1169 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BROS_STATION_NW
), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
1170 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BROS_STATION_NE
), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
1171 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BROS_STATION_X
), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
1172 NWidget(NWID_SPACER
), SetFill(1, 0),
1174 NWidget(NWID_SPACER
), SetMinimalSize(0, 2),
1175 NWidget(NWID_HORIZONTAL
), SetPIP(0, 2, 0),
1176 NWidget(NWID_SPACER
), SetFill(1, 0),
1177 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BROS_STATION_SW
), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
1178 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BROS_STATION_SE
), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
1179 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BROS_STATION_Y
), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
1180 NWidget(NWID_SPACER
), SetFill(1, 0),
1182 NWidget(WWT_LABEL
, COLOUR_DARK_GREEN
, WID_BROS_INFO
), SetPadding(WD_FRAMERECT_TOP
, WD_FRAMERECT_RIGHT
, WD_FRAMERECT_BOTTOM
, WD_FRAMERECT_LEFT
), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE
, STR_NULL
), SetFill(1, 0),
1183 NWidget(NWID_HORIZONTAL
), SetPIP(2, 0, 2),
1184 NWidget(NWID_SPACER
), SetFill(1, 0),
1185 NWidget(WWT_TEXTBTN
, COLOUR_GREY
, WID_BROS_LT_OFF
), SetMinimalSize(60, 12),
1186 SetDataTip(STR_STATION_BUILD_COVERAGE_OFF
, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP
),
1187 NWidget(WWT_TEXTBTN
, COLOUR_GREY
, WID_BROS_LT_ON
), SetMinimalSize(60, 12),
1188 SetDataTip(STR_STATION_BUILD_COVERAGE_ON
, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP
),
1189 NWidget(NWID_SPACER
), SetFill(1, 0),
1191 NWidget(WWT_EMPTY
, COLOUR_DARK_GREEN
, WID_BROS_ACCEPTANCE
), SetPadding(0, WD_FRAMERECT_RIGHT
, 0, WD_FRAMERECT_LEFT
), SetResize(0, 1),
1195 static WindowDesc
_road_station_picker_desc(
1196 WDP_AUTO
, nullptr, 0, 0,
1197 WC_BUS_STATION
, WC_BUILD_TOOLBAR
,
1199 _nested_road_station_picker_widgets
, lengthof(_nested_road_station_picker_widgets
)
1202 /** Widget definition of the build tram station window */
1203 static const NWidgetPart _nested_tram_station_picker_widgets
[] = {
1204 NWidget(NWID_HORIZONTAL
),
1205 NWidget(WWT_CLOSEBOX
, COLOUR_DARK_GREEN
),
1206 NWidget(WWT_CAPTION
, COLOUR_DARK_GREEN
, WID_BROS_CAPTION
),
1208 NWidget(WWT_PANEL
, COLOUR_DARK_GREEN
, WID_BROS_BACKGROUND
),
1209 NWidget(NWID_SPACER
), SetMinimalSize(0, 3),
1210 NWidget(NWID_HORIZONTAL
), SetPIP(0, 2, 0),
1211 NWidget(NWID_SPACER
), SetFill(1, 0),
1212 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BROS_STATION_X
), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
1213 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_BROS_STATION_Y
), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
1214 NWidget(NWID_SPACER
), SetFill(1, 0),
1216 NWidget(WWT_LABEL
, COLOUR_DARK_GREEN
, WID_BROS_INFO
), SetPadding(WD_FRAMERECT_TOP
, WD_FRAMERECT_RIGHT
, WD_FRAMERECT_BOTTOM
, WD_FRAMERECT_LEFT
), SetMinimalSize(140, 14), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE
, STR_NULL
), SetFill(1, 0),
1217 NWidget(NWID_HORIZONTAL
), SetPIP(2, 0, 2),
1218 NWidget(NWID_SPACER
), SetFill(1, 0),
1219 NWidget(WWT_TEXTBTN
, COLOUR_GREY
, WID_BROS_LT_OFF
), SetMinimalSize(60, 12),
1220 SetDataTip(STR_STATION_BUILD_COVERAGE_OFF
, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP
),
1221 NWidget(WWT_TEXTBTN
, COLOUR_GREY
, WID_BROS_LT_ON
), SetMinimalSize(60, 12),
1222 SetDataTip(STR_STATION_BUILD_COVERAGE_ON
, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP
),
1223 NWidget(NWID_SPACER
), SetFill(1, 0),
1225 NWidget(WWT_EMPTY
, COLOUR_DARK_GREEN
, WID_BROS_ACCEPTANCE
), SetPadding(0, WD_FRAMERECT_RIGHT
, 0, WD_FRAMERECT_LEFT
), SetResize(0, 1),
1229 static WindowDesc
_tram_station_picker_desc(
1230 WDP_AUTO
, nullptr, 0, 0,
1231 WC_BUS_STATION
, WC_BUILD_TOOLBAR
,
1233 _nested_tram_station_picker_widgets
, lengthof(_nested_tram_station_picker_widgets
)
1236 static void ShowRVStationPicker(Window
*parent
, RoadStopType rs
)
1238 new BuildRoadStationWindow(RoadTypeIsRoad(_cur_roadtype
) ? &_road_station_picker_desc
: &_tram_station_picker_desc
, parent
, rs
);
1241 void InitializeRoadGui()
1243 _road_depot_orientation
= DIAGDIR_NW
;
1244 _road_station_picker_orientation
= DIAGDIR_NW
;
1248 * I really don't know why rail_gui.cpp has this too, shouldn't be included in the other one?
1250 void InitializeRoadGUI()
1252 BuildRoadToolbarWindow
*w
= dynamic_cast<BuildRoadToolbarWindow
*>(FindWindowById(WC_BUILD_TOOLBAR
, TRANSPORT_ROAD
));
1253 if (w
!= nullptr) w
->ModifyRoadType(_cur_roadtype
);
1256 DropDownList
GetRoadTypeDropDownList(RoadTramTypes rtts
, bool for_replacement
, bool all_option
)
1258 RoadTypes used_roadtypes
;
1259 RoadTypes avail_roadtypes
;
1261 const Company
*c
= Company::Get(_local_company
);
1263 /* Find the used roadtypes. */
1264 if (for_replacement
) {
1265 avail_roadtypes
= GetCompanyRoadTypes(c
->index
, false);
1266 used_roadtypes
= GetRoadTypes(false);
1268 avail_roadtypes
= c
->avail_roadtypes
;
1269 used_roadtypes
= GetRoadTypes(true);
1272 /* Filter listed road types */
1273 if (!HasBit(rtts
, RTT_ROAD
)) used_roadtypes
&= _roadtypes_type
;
1274 if (!HasBit(rtts
, RTT_TRAM
)) used_roadtypes
&= ~_roadtypes_type
;
1279 list
.emplace_back(new DropDownListStringItem(STR_REPLACE_ALL_ROADTYPE
, INVALID_ROADTYPE
, false));
1282 Dimension d
= { 0, 0 };
1283 /* Get largest icon size, to ensure text is aligned on each menu item. */
1284 if (!for_replacement
) {
1285 for (const auto &rt
: _sorted_roadtypes
) {
1286 if (!HasBit(used_roadtypes
, rt
)) continue;
1287 const RoadTypeInfo
*rti
= GetRoadTypeInfo(rt
);
1288 d
= maxdim(d
, GetSpriteSize(rti
->gui_sprites
.build_x_road
));
1292 for (const auto &rt
: _sorted_roadtypes
) {
1293 /* If it's not used ever, don't show it to the user. */
1294 if (!HasBit(used_roadtypes
, rt
)) continue;
1296 const RoadTypeInfo
*rti
= GetRoadTypeInfo(rt
);
1298 DropDownListParamStringItem
*item
;
1299 if (for_replacement
) {
1300 item
= new DropDownListParamStringItem(rti
->strings
.replace_text
, rt
, !HasBit(avail_roadtypes
, rt
));
1302 StringID str
= rti
->max_speed
> 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY
: STR_JUST_STRING
;
1303 DropDownListIconItem
*iconitem
= new DropDownListIconItem(rti
->gui_sprites
.build_x_road
, PAL_NONE
, str
, rt
, !HasBit(avail_roadtypes
, rt
));
1304 iconitem
->SetDimension(d
);
1307 item
->SetParam(0, rti
->strings
.menu_text
);
1308 item
->SetParam(1, rti
->max_speed
/ 2);
1309 list
.emplace_back(item
);
1312 if (list
.size() == 0) {
1313 /* Empty dropdowns are not allowed */
1314 list
.emplace_back(new DropDownListStringItem(STR_NONE
, INVALID_ROADTYPE
, true));
1320 DropDownList
GetScenRoadTypeDropDownList(RoadTramTypes rtts
)
1322 RoadTypes avail_roadtypes
= GetRoadTypes(false);
1323 avail_roadtypes
= AddDateIntroducedRoadTypes(avail_roadtypes
, _date
);
1324 RoadTypes used_roadtypes
= GetRoadTypes(true);
1326 /* Filter listed road types */
1327 if (!HasBit(rtts
, RTT_ROAD
)) used_roadtypes
&= _roadtypes_type
;
1328 if (!HasBit(rtts
, RTT_TRAM
)) used_roadtypes
&= ~_roadtypes_type
;
1332 /* If it's not used ever, don't show it to the user. */
1333 Dimension d
= { 0, 0 };
1334 for (const auto &rt
: _sorted_roadtypes
) {
1335 if (!HasBit(used_roadtypes
, rt
)) continue;
1336 const RoadTypeInfo
*rti
= GetRoadTypeInfo(rt
);
1337 d
= maxdim(d
, GetSpriteSize(rti
->gui_sprites
.build_x_road
));
1339 for (const auto &rt
: _sorted_roadtypes
) {
1340 if (!HasBit(used_roadtypes
, rt
)) continue;
1342 const RoadTypeInfo
*rti
= GetRoadTypeInfo(rt
);
1344 StringID str
= rti
->max_speed
> 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY
: STR_JUST_STRING
;
1345 DropDownListIconItem
*item
= new DropDownListIconItem(rti
->gui_sprites
.build_x_road
, PAL_NONE
, str
, rt
, !HasBit(avail_roadtypes
, rt
));
1346 item
->SetDimension(d
);
1347 item
->SetParam(0, rti
->strings
.menu_text
);
1348 item
->SetParam(1, rti
->max_speed
/ 2);
1349 list
.emplace_back(item
);
1352 if (list
.size() == 0) {
1353 /* Empty dropdowns are not allowed */
1354 list
.emplace_back(new DropDownListStringItem(STR_NONE
, -1, true));