OpenTTD
road_gui.cpp
Go to the documentation of this file.
1 /* $Id: road_gui.cpp 27134 2015-02-01 20:54:24Z frosch $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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  */
9 
12 #include "stdafx.h"
13 #include "gui.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 "road_cmd.h"
20 #include "station_func.h"
21 #include "window_func.h"
22 #include "vehicle_func.h"
23 #include "sound_func.h"
24 #include "company_func.h"
25 #include "tunnelbridge.h"
26 #include "tunnelbridge_map.h"
27 #include "tilehighlight_func.h"
28 #include "company_base.h"
29 #include "hotkeys.h"
30 #include "road_gui.h"
31 #include "zoom_func.h"
32 
33 #include "widgets/road_widget.h"
34 
35 #include "table/strings.h"
36 
37 #include "safeguards.h"
38 
39 static void ShowRVStationPicker(Window *parent, RoadStopType rs);
40 static void ShowRoadDepotPicker(Window *parent);
41 
42 static bool _remove_button_clicked;
43 static bool _one_way_button_clicked;
44 
49 enum RoadFlags {
50  RF_NONE = 0x00,
51  RF_START_HALFROAD_Y = 0x01, // The start tile in Y-dir should have only a half road
52  RF_END_HALFROAD_Y = 0x02, // The end tile in Y-dir should have only a half road
53  RF_DIR_Y = 0x04, // The direction is Y-dir
54  RF_DIR_X = RF_NONE, // Dummy; Dir X is set when RF_DIR_Y is not set
55  RF_START_HALFROAD_X = 0x08, // The start tile in X-dir should have only a half road
56  RF_END_HALFROAD_X = 0x10, // The end tile in X-dir should have only a half road
57 };
59 
60 static RoadFlags _place_road_flag;
61 
62 static RoadType _cur_roadtype;
63 
64 static DiagDirection _road_depot_orientation;
65 static DiagDirection _road_station_picker_orientation;
66 
67 void CcPlaySound1D(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
68 {
69  if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_1F_SPLAT_OTHER, tile);
70 }
71 
76 static void PlaceRoad_Bridge(TileIndex tile, Window *w)
77 {
78  if (IsBridgeTile(tile)) {
79  TileIndex other_tile = GetOtherTunnelBridgeEnd(tile);
80  Point pt = {0, 0};
81  w->OnPlaceMouseUp(VPM_X_OR_Y, DDSP_BUILD_BRIDGE, pt, other_tile, tile);
82  } else {
84  }
85 }
86 
96 void CcBuildRoadTunnel(const CommandCost &result, TileIndex start_tile, uint32 p1, uint32 p2)
97 {
98  if (result.Succeeded()) {
99  if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_SPLAT_OTHER, start_tile);
100  if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
101 
102  DiagDirection start_direction = ReverseDiagDir(GetTunnelBridgeDirection(start_tile));
103  ConnectRoadToStructure(start_tile, start_direction);
104 
105  TileIndex end_tile = GetOtherTunnelBridgeEnd(start_tile);
106  DiagDirection end_direction = ReverseDiagDir(GetTunnelBridgeDirection(end_tile));
107  ConnectRoadToStructure(end_tile, end_direction);
108  } else {
110  }
111 }
112 
114 struct RoadTypeInfo {
120 
123 
127 };
128 
130 static const RoadTypeInfo _road_type_infos[] = {
131  {
132  STR_ERROR_CAN_T_BUILD_ROAD_HERE,
133  STR_ERROR_CAN_T_REMOVE_ROAD_FROM,
134  STR_ERROR_CAN_T_BUILD_ROAD_DEPOT,
135  { STR_ERROR_CAN_T_BUILD_BUS_STATION, STR_ERROR_CAN_T_BUILD_TRUCK_STATION },
136  { STR_ERROR_CAN_T_REMOVE_BUS_STATION, STR_ERROR_CAN_T_REMOVE_TRUCK_STATION },
137  { STR_STATION_BUILD_BUS_ORIENTATION, STR_STATION_BUILD_TRUCK_ORIENTATION },
138  { STR_STATION_BUILD_BUS_ORIENTATION_TOOLTIP, STR_STATION_BUILD_TRUCK_ORIENTATION_TOOLTIP },
139 
140  SPR_CURSOR_ROAD_NESW,
141  SPR_CURSOR_ROAD_NWSE,
142  SPR_CURSOR_AUTOROAD,
143  },
144  {
145  STR_ERROR_CAN_T_BUILD_TRAMWAY_HERE,
146  STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM,
147  STR_ERROR_CAN_T_BUILD_TRAM_DEPOT,
148  { STR_ERROR_CAN_T_BUILD_PASSENGER_TRAM_STATION, STR_ERROR_CAN_T_BUILD_CARGO_TRAM_STATION },
149  { STR_ERROR_CAN_T_REMOVE_PASSENGER_TRAM_STATION, STR_ERROR_CAN_T_REMOVE_CARGO_TRAM_STATION },
150  { STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION, STR_STATION_BUILD_CARGO_TRAM_ORIENTATION },
151  { STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION_TOOLTIP, STR_STATION_BUILD_CARGO_TRAM_ORIENTATION_TOOLTIP },
152 
153  SPR_CURSOR_TRAMWAY_NESW,
154  SPR_CURSOR_TRAMWAY_NWSE,
155  SPR_CURSOR_AUTOTRAM,
156  },
157 };
158 
165 {
166  tile += TileOffsByDiagDir(direction);
167  /* if there is a roadpiece just outside of the station entrance, build a connecting route */
168  if (IsNormalRoadTile(tile)) {
169  if (GetRoadBits(tile, _cur_roadtype) != ROAD_NONE) {
170  DoCommandP(tile, _cur_roadtype << 4 | DiagDirToRoadBits(ReverseDiagDir(direction)), 0, CMD_BUILD_ROAD);
171  }
172  }
173 }
174 
175 void CcRoadDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
176 {
177  if (result.Failed()) return;
178 
179  DiagDirection dir = (DiagDirection)GB(p1, 0, 2);
180  if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_SPLAT_OTHER, tile);
181  if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
182  ConnectRoadToStructure(tile, dir);
183 }
184 
199 void CcRoadStop(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
200 {
201  if (result.Failed()) return;
202 
203  DiagDirection dir = (DiagDirection)GB(p2, 6, 2);
204  if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_SPLAT_OTHER, tile);
205  if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
206  TileArea roadstop_area(tile, GB(p1, 0, 8), GB(p1, 8, 8));
207  TILE_AREA_LOOP(cur_tile, roadstop_area) {
208  ConnectRoadToStructure(cur_tile, dir);
209  /* For a drive-through road stop build connecting road for other entrance. */
210  if (HasBit(p2, 1)) ConnectRoadToStructure(cur_tile, ReverseDiagDir(dir));
211  }
212 }
213 
224 static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, uint32 cmd)
225 {
226  uint8 ddir = _road_station_picker_orientation;
227  SB(p2, 16, 16, INVALID_STATION); // no station to join
228 
229  if (ddir >= DIAGDIR_END) {
230  SetBit(p2, 1); // It's a drive-through stop.
231  ddir -= DIAGDIR_END; // Adjust picker result to actual direction.
232  }
233  p2 |= ddir << 6; // Set the DiagDirecion into p2 bits 6 and 7.
234 
235  TileArea ta(start_tile, end_tile);
236  CommandContainer cmdcont = { ta.tile, ta.w | ta.h << 8, p2, cmd, CcRoadStop, "" };
237  ShowSelectStationIfNeeded(cmdcont, ta);
238 }
239 
245 {
248  } else {
249  if (_road_station_picker_orientation < DIAGDIR_END) { // Not a drive-through stop.
250  VpStartPlaceSizing(tile, (DiagDirToAxis(_road_station_picker_orientation) == AXIS_X) ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_BUSSTOP);
251  } else {
253  }
254  VpSetPlaceSizingLimit(_settings_game.station.station_spread);
255  }
256 }
257 
263 {
266  } else {
267  if (_road_station_picker_orientation < DIAGDIR_END) { // Not a drive-through stop.
268  VpStartPlaceSizing(tile, (DiagDirToAxis(_road_station_picker_orientation) == AXIS_X) ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_TRUCKSTOP);
269  } else {
271  }
272  VpSetPlaceSizingLimit(_settings_game.station.station_spread);
273  }
274 }
275 
276 typedef void OnButtonClick(Window *w);
277 
283 {
287  SetSelectionRed(_remove_button_clicked);
288 }
289 
296 {
297  if (w->IsWidgetDisabled(WID_ROT_REMOVE)) return false;
298 
299  /* allow ctrl to switch remove mode only for these widgets */
300  for (uint i = WID_ROT_ROAD_X; i <= WID_ROT_AUTOROAD; i++) {
301  if (w->IsWidgetLowered(i)) {
303  return true;
304  }
305  }
306 
307  return false;
308 }
309 
313 
315  {
316  this->InitNested(window_number);
317  this->SetWidgetsDisabledState(true,
321 
322  this->OnInvalidateData();
324 
326  }
327 
329  {
331  }
332 
338  virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
339  {
340  if (!gui_scope) return;
346  }
347 
354  {
355  /* The remove and the one way button state is driven
356  * by the other buttons so they don't act on themselves.
357  * Both are only valid if they are able to apply as options. */
358  switch (clicked_widget) {
359  case WID_ROT_REMOVE:
362  break;
363 
364  case WID_ROT_ONE_WAY:
367  break;
368 
369  case WID_ROT_BUS_STATION:
372  this->SetWidgetDisabledState(WID_ROT_REMOVE, !this->IsWidgetLowered(clicked_widget));
373  break;
374 
375  case WID_ROT_ROAD_X:
376  case WID_ROT_ROAD_Y:
377  case WID_ROT_AUTOROAD:
378  this->SetWidgetsDisabledState(!this->IsWidgetLowered(clicked_widget),
382  break;
383 
384  default:
385  /* When any other buttons than road/station, raise and
386  * disable the removal button */
387  this->SetWidgetsDisabledState(true,
391  this->SetWidgetsLoweredState(false,
395  break;
396  }
397  }
398 
399  virtual void OnClick(Point pt, int widget, int click_count)
400  {
401  _remove_button_clicked = false;
402  _one_way_button_clicked = false;
403  switch (widget) {
404  case WID_ROT_ROAD_X:
405  HandlePlacePushButton(this, WID_ROT_ROAD_X, _road_type_infos[_cur_roadtype].cursor_nwse, HT_RECT);
406  this->last_started_action = widget;
407  break;
408 
409  case WID_ROT_ROAD_Y:
410  HandlePlacePushButton(this, WID_ROT_ROAD_Y, _road_type_infos[_cur_roadtype].cursor_nesw, HT_RECT);
411  this->last_started_action = widget;
412  break;
413 
414  case WID_ROT_AUTOROAD:
415  HandlePlacePushButton(this, WID_ROT_AUTOROAD, _road_type_infos[_cur_roadtype].cursor_autoroad, HT_RECT);
416  this->last_started_action = widget;
417  break;
418 
419  case WID_ROT_DEMOLISH:
421  this->last_started_action = widget;
422  break;
423 
424  case WID_ROT_DEPOT:
425  if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD)) return;
426  if (HandlePlacePushButton(this, WID_ROT_DEPOT, SPR_CURSOR_ROAD_DEPOT, HT_RECT)) {
427  ShowRoadDepotPicker(this);
428  this->last_started_action = widget;
429  }
430  break;
431 
432  case WID_ROT_BUS_STATION:
433  if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD)) return;
434  if (HandlePlacePushButton(this, WID_ROT_BUS_STATION, SPR_CURSOR_BUS_STATION, HT_RECT)) {
435  ShowRVStationPicker(this, ROADSTOP_BUS);
436  this->last_started_action = widget;
437  }
438  break;
439 
441  if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD)) return;
442  if (HandlePlacePushButton(this, WID_ROT_TRUCK_STATION, SPR_CURSOR_TRUCK_STATION, HT_RECT)) {
443  ShowRVStationPicker(this, ROADSTOP_TRUCK);
444  this->last_started_action = widget;
445  }
446  break;
447 
448  case WID_ROT_ONE_WAY:
449  if (this->IsWidgetDisabled(WID_ROT_ONE_WAY)) return;
450  this->SetDirty();
452  SetSelectionRed(false);
453  break;
454 
456  HandlePlacePushButton(this, WID_ROT_BUILD_BRIDGE, SPR_CURSOR_BRIDGE, HT_RECT);
457  this->last_started_action = widget;
458  break;
459 
461  HandlePlacePushButton(this, WID_ROT_BUILD_TUNNEL, SPR_CURSOR_ROAD_TUNNEL, HT_SPECIAL);
462  this->last_started_action = widget;
463  break;
464 
465  case WID_ROT_REMOVE:
466  if (this->IsWidgetDisabled(WID_ROT_REMOVE)) return;
467 
470  if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
471  break;
472 
473  default: NOT_REACHED();
474  }
477  }
478 
479  virtual EventState OnHotkey(int hotkey)
480  {
481  MarkTileDirtyByTile(TileVirtXY(_thd.pos.x, _thd.pos.y)); // redraw tile selection
482  return Window::OnHotkey(hotkey);
483  }
484 
485  virtual void OnPlaceObject(Point pt, TileIndex tile)
486  {
488  _one_way_button_clicked = this->IsWidgetLowered(WID_ROT_ONE_WAY);
489  switch (this->last_started_action) {
490  case WID_ROT_ROAD_X:
491  _place_road_flag = RF_DIR_X;
492  if (_tile_fract_coords.x >= 8) _place_road_flag |= RF_START_HALFROAD_X;
494  break;
495 
496  case WID_ROT_ROAD_Y:
497  _place_road_flag = RF_DIR_Y;
498  if (_tile_fract_coords.y >= 8) _place_road_flag |= RF_START_HALFROAD_Y;
500  break;
501 
502  case WID_ROT_AUTOROAD:
503  _place_road_flag = RF_NONE;
504  if (_tile_fract_coords.x >= 8) _place_road_flag |= RF_START_HALFROAD_X;
505  if (_tile_fract_coords.y >= 8) _place_road_flag |= RF_START_HALFROAD_Y;
507  break;
508 
509  case WID_ROT_DEMOLISH:
511  break;
512 
513  case WID_ROT_DEPOT:
514  DoCommandP(tile, _cur_roadtype << 2 | _road_depot_orientation, 0,
515  CMD_BUILD_ROAD_DEPOT | CMD_MSG(_road_type_infos[_cur_roadtype].err_depot), CcRoadDepot);
516  break;
517 
518  case WID_ROT_BUS_STATION:
519  PlaceRoad_BusStation(tile);
520  break;
521 
524  break;
525 
527  PlaceRoad_Bridge(tile, this);
528  break;
529 
531  DoCommandP(tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), 0,
532  CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRoadTunnel);
533  break;
534 
535  default: NOT_REACHED();
536  }
537  }
538 
539  virtual void OnPlaceObjectAbort()
540  {
541  this->RaiseButtons();
542  this->SetWidgetsDisabledState(true,
548 
554  }
555 
556  virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
557  {
558  /* Here we update the end tile flags
559  * of the road placement actions.
560  * At first we reset the end halfroad
561  * bits and if needed we set them again. */
562  switch (select_proc) {
564  _place_road_flag &= ~RF_END_HALFROAD_X;
565  if (pt.x & 8) _place_road_flag |= RF_END_HALFROAD_X;
566  break;
567 
569  _place_road_flag &= ~RF_END_HALFROAD_Y;
570  if (pt.y & 8) _place_road_flag |= RF_END_HALFROAD_Y;
571  break;
572 
573  case DDSP_PLACE_AUTOROAD:
574  _place_road_flag &= ~(RF_END_HALFROAD_Y | RF_END_HALFROAD_X);
575  if (pt.y & 8) _place_road_flag |= RF_END_HALFROAD_Y;
576  if (pt.x & 8) _place_road_flag |= RF_END_HALFROAD_X;
577 
578  /* For autoroad we need to update the
579  * direction of the road */
580  if (_thd.size.x > _thd.size.y || (_thd.size.x == _thd.size.y &&
581  ( (_tile_fract_coords.x < _tile_fract_coords.y && (_tile_fract_coords.x + _tile_fract_coords.y) < 16) ||
582  (_tile_fract_coords.x > _tile_fract_coords.y && (_tile_fract_coords.x + _tile_fract_coords.y) > 16) ))) {
583  /* Set dir = X */
584  _place_road_flag &= ~RF_DIR_Y;
585  } else {
586  /* Set dir = Y */
587  _place_road_flag |= RF_DIR_Y;
588  }
589 
590  break;
591 
592  default:
593  break;
594  }
595 
596  VpSelectTilesWithMethod(pt.x, pt.y, select_method);
597  }
598 
599  virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
600  {
601  if (pt.x != -1) {
602  switch (select_proc) {
603  default: NOT_REACHED();
604  case DDSP_BUILD_BRIDGE:
605  if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
606  ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, RoadTypeToRoadTypes(_cur_roadtype));
607  break;
608 
609  case DDSP_DEMOLISH_AREA:
610  GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
611  break;
612 
615  case DDSP_PLACE_AUTOROAD:
616  /* Flag description:
617  * Use the first three bits (0x07) if dir == Y
618  * else use the last 2 bits (X dir has
619  * not the 3rd bit set) */
620  _place_road_flag = (RoadFlags)((_place_road_flag & RF_DIR_Y) ? (_place_road_flag & 0x07) : (_place_road_flag >> 3));
621 
622  DoCommandP(start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 5),
624  CMD_REMOVE_LONG_ROAD | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_road) :
625  CMD_BUILD_LONG_ROAD | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_road), CcPlaySound1D);
626  break;
627 
628  case DDSP_BUILD_BUSSTOP:
629  PlaceRoadStop(start_tile, end_tile, (_ctrl_pressed << 5) | RoadTypeToRoadTypes(_cur_roadtype) << 2 | ROADSTOP_BUS, CMD_BUILD_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_station[ROADSTOP_BUS]));
630  break;
631 
633  PlaceRoadStop(start_tile, end_tile, (_ctrl_pressed << 5) | RoadTypeToRoadTypes(_cur_roadtype) << 2 | ROADSTOP_TRUCK, CMD_BUILD_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_station[ROADSTOP_TRUCK]));
634  break;
635 
636  case DDSP_REMOVE_BUSSTOP: {
637  TileArea ta(start_tile, end_tile);
638  DoCommandP(ta.tile, ta.w | ta.h << 8, ROADSTOP_BUS, CMD_REMOVE_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_station[ROADSTOP_BUS]), CcPlaySound1D);
639  break;
640  }
641 
642  case DDSP_REMOVE_TRUCKSTOP: {
643  TileArea ta(start_tile, end_tile);
644  DoCommandP(ta.tile, ta.w | ta.h << 8, ROADSTOP_TRUCK, CMD_REMOVE_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_station[ROADSTOP_TRUCK]), CcPlaySound1D);
645  break;
646  }
647  }
648  }
649  }
650 
651  virtual void OnPlacePresize(Point pt, TileIndex tile)
652  {
653  DoCommand(tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), 0, DC_AUTO, CMD_BUILD_TUNNEL);
655  }
656 
658  {
659  if (RoadToolbar_CtrlChanged(this)) return ES_HANDLED;
660  return ES_NOT_HANDLED;
661  }
662 
663  static HotkeyList hotkeys;
664 };
665 
672 {
673  Window *w = NULL;
674  switch (_game_mode) {
675  case GM_NORMAL: {
676  extern RoadType _last_built_roadtype;
677  w = ShowBuildRoadToolbar(_last_built_roadtype);
678  break;
679  }
680 
681  case GM_EDITOR:
683  break;
684 
685  default:
686  break;
687  }
688 
689  if (w == NULL) return ES_NOT_HANDLED;
690  return w->OnHotkey(hotkey);
691 }
692 
693 static Hotkey roadtoolbar_hotkeys[] = {
694  Hotkey('1', "build_x", WID_ROT_ROAD_X),
695  Hotkey('2', "build_y", WID_ROT_ROAD_Y),
696  Hotkey('3', "autoroad", WID_ROT_AUTOROAD),
697  Hotkey('4', "demolish", WID_ROT_DEMOLISH),
698  Hotkey('5', "depot", WID_ROT_DEPOT),
699  Hotkey('6', "bus_station", WID_ROT_BUS_STATION),
700  Hotkey('7', "truck_station", WID_ROT_TRUCK_STATION),
701  Hotkey('8', "oneway", WID_ROT_ONE_WAY),
702  Hotkey('B', "bridge", WID_ROT_BUILD_BRIDGE),
703  Hotkey('T', "tunnel", WID_ROT_BUILD_TUNNEL),
704  Hotkey('R', "remove", WID_ROT_REMOVE),
705  HOTKEY_LIST_END
706 };
707 HotkeyList BuildRoadToolbarWindow::hotkeys("roadtoolbar", roadtoolbar_hotkeys, RoadToolbarGlobalHotkeys);
708 
709 
710 static const NWidgetPart _nested_build_road_widgets[] = {
712  NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
713  NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
714  NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
715  EndContainer(),
717  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_X),
718  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_X_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION),
719  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_Y),
720  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_Y_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION),
721  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_AUTOROAD),
722  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOROAD, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD),
723  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEMOLISH),
724  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
725  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEPOT),
726  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_DEPOT, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT),
727  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUS_STATION),
728  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_BUS_STATION, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION),
729  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_TRUCK_STATION),
730  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRUCK_BAY, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY),
731  NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
732  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ONE_WAY),
733  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_ONE_WAY, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD),
734  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE),
735  SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE),
736  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL),
737  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL),
738  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_REMOVE),
739  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD),
740  EndContainer(),
741 };
742 
743 static WindowDesc _build_road_desc(
744  WDP_ALIGN_TOOLBAR, "toolbar_road", 0, 0,
747  _nested_build_road_widgets, lengthof(_nested_build_road_widgets),
748  &BuildRoadToolbarWindow::hotkeys
749 );
750 
751 static const NWidgetPart _nested_build_tramway_widgets[] = {
753  NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
754  NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
755  NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
756  EndContainer(),
758  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_X),
759  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRAMWAY_X_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION),
760  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_Y),
761  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRAMWAY_Y_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION),
762  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_AUTOROAD),
763  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOTRAM, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM),
764  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEMOLISH),
765  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
766  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEPOT),
767  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_DEPOT, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT),
768  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUS_STATION),
769  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_BUS_STATION, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION),
770  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_TRUCK_STATION),
771  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRUCK_BAY, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION),
772  NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
773  NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_ROT_ONE_WAY), SetMinimalSize(0, 0),
774  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE),
775  SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE),
776  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL),
777  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL),
778  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_REMOVE),
779  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS),
780  EndContainer(),
781 };
782 
783 static WindowDesc _build_tramway_desc(
784  WDP_ALIGN_TOOLBAR, "toolbar_tramway", 0, 0,
787  _nested_build_tramway_widgets, lengthof(_nested_build_tramway_widgets),
788  &BuildRoadToolbarWindow::hotkeys
789 );
790 
799 {
800  if (!Company::IsValidID(_local_company)) return NULL;
801  _cur_roadtype = roadtype;
802 
804  return AllocateWindowDescFront<BuildRoadToolbarWindow>(roadtype == ROADTYPE_ROAD ? &_build_road_desc : &_build_tramway_desc, TRANSPORT_ROAD);
805 }
806 
807 static const NWidgetPart _nested_build_road_scen_widgets[] = {
809  NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
810  NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
811  NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
812  EndContainer(),
814  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_X),
815  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_X_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION),
816  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_Y),
817  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_Y_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION),
818  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_AUTOROAD),
819  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOROAD, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD),
820  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEMOLISH),
821  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
822  NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
823  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ONE_WAY),
824  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_ONE_WAY, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD),
825  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE),
826  SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE),
827  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL),
828  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL),
829  NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_REMOVE),
830  SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD),
831  EndContainer(),
832 };
833 
834 static WindowDesc _build_road_scen_desc(
835  WDP_AUTO, "toolbar_road_scen", 0, 0,
838  _nested_build_road_scen_widgets, lengthof(_nested_build_road_scen_widgets),
839  &BuildRoadToolbarWindow::hotkeys
840 );
841 
847 {
848  _cur_roadtype = ROADTYPE_ROAD;
849  return AllocateWindowDescFront<BuildRoadToolbarWindow>(&_build_road_scen_desc, TRANSPORT_ROAD);
850 }
851 
854  {
855  this->CreateNestedTree();
856 
857  this->LowerWidget(_road_depot_orientation + WID_BROD_DEPOT_NE);
858  if ( _cur_roadtype == ROADTYPE_TRAM) {
859  this->GetWidget<NWidgetCore>(WID_BROD_CAPTION)->widget_data = STR_BUILD_DEPOT_TRAM_ORIENTATION_CAPTION;
860  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;
861  }
862 
864  }
865 
866  virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
867  {
868  if (!IsInsideMM(widget, WID_BROD_DEPOT_NE, WID_BROD_DEPOT_NW + 1)) return;
869 
870  size->width = ScaleGUITrad(64) + 2;
871  size->height = ScaleGUITrad(48) + 2;
872  }
873 
874  virtual void DrawWidget(const Rect &r, int widget) const
875  {
876  if (!IsInsideMM(widget, WID_BROD_DEPOT_NE, WID_BROD_DEPOT_NW + 1)) return;
877 
878  DrawRoadDepotSprite(r.left + 1 + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), (DiagDirection)(widget - WID_BROD_DEPOT_NE + DIAGDIR_NE), _cur_roadtype);
879  }
880 
881  virtual void OnClick(Point pt, int widget, int click_count)
882  {
883  switch (widget) {
884  case WID_BROD_DEPOT_NW:
885  case WID_BROD_DEPOT_NE:
886  case WID_BROD_DEPOT_SW:
887  case WID_BROD_DEPOT_SE:
888  this->RaiseWidget(_road_depot_orientation + WID_BROD_DEPOT_NE);
889  _road_depot_orientation = (DiagDirection)(widget - WID_BROD_DEPOT_NE);
890  this->LowerWidget(_road_depot_orientation + WID_BROD_DEPOT_NE);
891  if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
892  this->SetDirty();
893  break;
894 
895  default:
896  break;
897  }
898  }
899 };
900 
901 static const NWidgetPart _nested_build_road_depot_widgets[] = {
903  NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
904  NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROD_CAPTION), SetDataTip(STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
905  EndContainer(),
906  NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
909  NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
911  NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_NW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
912  EndContainer(),
914  NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_SW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
915  EndContainer(),
916  EndContainer(),
919  NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_NE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
920  EndContainer(),
922  NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_SE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
923  EndContainer(),
924  EndContainer(),
925  NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
926  EndContainer(),
928  EndContainer(),
929 };
930 
931 static WindowDesc _build_road_depot_desc(
932  WDP_AUTO, NULL, 0, 0,
935  _nested_build_road_depot_widgets, lengthof(_nested_build_road_depot_widgets)
936 );
937 
938 static void ShowRoadDepotPicker(Window *parent)
939 {
940  new BuildRoadDepotWindow(&_build_road_depot_desc, parent);
941 }
942 
945  {
946  this->CreateNestedTree();
947 
948  /* Trams don't have non-drivethrough stations */
949  if (_cur_roadtype == ROADTYPE_TRAM && _road_station_picker_orientation < DIAGDIR_END) {
950  _road_station_picker_orientation = DIAGDIR_END;
951  }
952  this->SetWidgetsDisabledState(_cur_roadtype == ROADTYPE_TRAM,
958 
959  this->GetWidget<NWidgetCore>(WID_BROS_CAPTION)->widget_data = _road_type_infos[_cur_roadtype].picker_title[rs];
960  for (uint i = WID_BROS_STATION_NE; i < WID_BROS_LT_OFF; i++) this->GetWidget<NWidgetCore>(i)->tool_tip = _road_type_infos[_cur_roadtype].picker_tooltip[rs];
961 
962  this->LowerWidget(_road_station_picker_orientation + WID_BROS_STATION_NE);
963  this->LowerWidget(_settings_client.gui.station_show_coverage + WID_BROS_LT_OFF);
964 
966 
968  }
969 
970  virtual ~BuildRoadStationWindow()
971  {
973  }
974 
975  virtual void OnPaint()
976  {
977  this->DrawWidgets();
978 
981  SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
982  } else {
983  SetTileSelectSize(1, 1);
984  }
985 
986  /* 'Accepts' and 'Supplies' texts. */
988  int top = this->GetWidget<NWidgetBase>(WID_BROS_LT_ON)->pos_y + this->GetWidget<NWidgetBase>(WID_BROS_LT_ON)->current_y + WD_PAR_VSEP_NORMAL;
989  NWidgetBase *back_nwi = this->GetWidget<NWidgetBase>(WID_BROS_BACKGROUND);
990  int right = back_nwi->pos_x + back_nwi->current_x;
991  int bottom = back_nwi->pos_y + back_nwi->current_y;
992  top = DrawStationCoverageAreaText(back_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, sct, rad, false) + WD_PAR_VSEP_NORMAL;
993  top = DrawStationCoverageAreaText(back_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, sct, rad, true) + WD_PAR_VSEP_NORMAL;
994  /* Resize background if the window is too small.
995  * Never make the window smaller to avoid oscillating if the size change affects the acceptance.
996  * (This is the case, if making the window bigger moves the mouse into the window.) */
997  if (top > bottom) {
998  ResizeWindow(this, 0, top - bottom);
999  }
1000  }
1001 
1002  virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
1003  {
1004  if (!IsInsideMM(widget, WID_BROS_STATION_NE, WID_BROS_STATION_Y + 1)) return;
1005 
1006  size->width = ScaleGUITrad(64) + 2;
1007  size->height = ScaleGUITrad(48) + 2;
1008  }
1009 
1010  virtual void DrawWidget(const Rect &r, int widget) const
1011  {
1012  if (!IsInsideMM(widget, WID_BROS_STATION_NE, WID_BROS_STATION_Y + 1)) return;
1013 
1014  StationType st = (this->window_class == WC_BUS_STATION) ? STATION_BUS : STATION_TRUCK;
1015  StationPickerDrawSprite(r.left + 1 + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), st, INVALID_RAILTYPE, widget < WID_BROS_STATION_X ? ROADTYPE_ROAD : _cur_roadtype, widget - WID_BROS_STATION_NE);
1016  }
1017 
1018  virtual void OnClick(Point pt, int widget, int click_count)
1019  {
1020  switch (widget) {
1021  case WID_BROS_STATION_NE:
1022  case WID_BROS_STATION_SE:
1023  case WID_BROS_STATION_SW:
1024  case WID_BROS_STATION_NW:
1025  case WID_BROS_STATION_X:
1026  case WID_BROS_STATION_Y:
1027  this->RaiseWidget(_road_station_picker_orientation + WID_BROS_STATION_NE);
1028  _road_station_picker_orientation = (DiagDirection)(widget - WID_BROS_STATION_NE);
1029  this->LowerWidget(_road_station_picker_orientation + WID_BROS_STATION_NE);
1030  if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
1031  this->SetDirty();
1033  break;
1034 
1035  case WID_BROS_LT_OFF:
1036  case WID_BROS_LT_ON:
1040  if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
1041  this->SetDirty();
1042  break;
1043 
1044  default:
1045  break;
1046  }
1047  }
1048 
1049  virtual void OnTick()
1050  {
1052  }
1053 };
1054 
1058  NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1059  NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROS_CAPTION),
1060  EndContainer(),
1061  NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BROS_BACKGROUND),
1063  NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0),
1064  NWidget(NWID_SPACER), SetFill(1, 0),
1067  NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetMinimalSize(66, 50), EndContainer(),
1068  NWidget(NWID_SPACER), SetFill(1, 0),
1069  EndContainer(),
1071  NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0),
1072  NWidget(NWID_SPACER), SetFill(1, 0),
1075  NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetMinimalSize(66, 50), EndContainer(),
1076  NWidget(NWID_SPACER), SetFill(1, 0),
1077  EndContainer(),
1079  NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
1080  NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_INFO), SetMinimalSize(140, 14), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL),
1081  NWidget(NWID_SPACER), SetFill(1, 0),
1082  EndContainer(),
1083  NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
1084  NWidget(NWID_SPACER), SetFill(1, 0),
1085  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_OFF), SetMinimalSize(60, 12),
1086  SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
1087  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_ON), SetMinimalSize(60, 12),
1088  SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
1089  NWidget(NWID_SPACER), SetFill(1, 0),
1090  EndContainer(),
1091  NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetResize(0, 1),
1092  EndContainer(),
1093 };
1094 
1095 static WindowDesc _rv_station_picker_desc(
1096  WDP_AUTO, NULL, 0, 0,
1099  _nested_rv_station_picker_widgets, lengthof(_nested_rv_station_picker_widgets)
1100 );
1101 
1102 static void ShowRVStationPicker(Window *parent, RoadStopType rs)
1103 {
1104  new BuildRoadStationWindow(&_rv_station_picker_desc, parent, rs);
1105 }
1106 
1107 void InitializeRoadGui()
1108 {
1109  _road_depot_orientation = DIAGDIR_NW;
1110  _road_station_picker_orientation = DIAGDIR_NW;
1111 }