# rail_gui.cpp

Go to the documentation of this file.

    00001 /* $Id: rail_gui.cpp 16364 2009-05-21 11:47:45Z rubidium $ */
    00002
    00005 #include "stdafx.h"
    00006 #include "gui.h"
    00007 #include "window_gui.h"
    00008 #include "station_gui.h"
    00009 #include "terraform_gui.h"
    00010 #include "viewport_func.h"
    00011 #include "gfx_func.h"
    00012 #include "command_func.h"
    00013 #include "waypoint.h"
    00014 #include "newgrf_station.h"
    00015 #include "company_base.h"
    00016 #include "strings_func.h"
    00017 #include "functions.h"
    00018 #include "window_func.h"
    00019 #include "date_func.h"
    00020 #include "sound_func.h"
    00021 #include "company_func.h"
    00022 #include "widgets/dropdown_type.h"
    00023 #include "tunnelbridge.h"
    00024 #include "tilehighlight_func.h"
    00025 #include "settings_type.h"
    00026
    00027 #include "station_map.h"
    00028 #include "tunnelbridge_map.h"
    00029
    00030 #include "table/sprites.h"
    00031 #include "table/strings.h"
    00032
    00033 static RailType _cur_railtype;
    00034 static bool _remove_button_clicked;
    00035 static DiagDirection _build_depot_direction;
    00036 static byte _waypoint_count = 1;
    00037 static byte _cur_waypoint_type;
    00038 static bool _convert_signal_button;
    00039 static SignalVariant _cur_signal_variant;
    00040 static SignalType _cur_signal_type;
    00041
    00042 /* Map the setting: default_signal_type to the corresponding signal type */
    00043 static const SignalType _default_signal_type[] = {SIGTYPE_NORMAL, SIGTYPE_PBS, SIGTYPE_PBS_ONEWAY};
    00044
    00045 struct RailStationGUISettings {
    00046   Axis orientation;
    00047
    00048   bool newstations;
    00049   StationClassIDByte station_class;
    00050   byte station_type;
    00051   byte station_count;
    00052 };
    00053 static RailStationGUISettings _railstation;
    00054
    00055
    00056 static void HandleStationPlacement(TileIndex start, TileIndex end);
    00057 static void ShowBuildTrainDepotPicker(Window *parent);
    00058 static void ShowBuildWaypointPicker(Window *parent);
    00059 static void ShowStationBuilder(Window *parent);
    00060 static void ShowSignalBuilder(Window *parent);
    00061
    00062 void CcPlaySound1E(bool success, TileIndex tile, uint32 p1, uint32 p2)
    00063 {
    00064   if (success) SndPlayTileFx(SND_20_SPLAT_2, tile);
    00065 }
    00066
    00067 static void GenericPlaceRail(TileIndex tile, int cmd)
    00068 {
    00069   DoCommandP(tile, _cur_railtype, cmd,
    00070     _remove_button_clicked ?
    00071     CMD_REMOVE_SINGLE_RAIL | CMD_MSG(STR_1012_CAN_T_REMOVE_RAILROAD_TRACK) :
    00072     CMD_BUILD_SINGLE_RAIL | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK),
    00073     CcPlaySound1E
    00074   );
    00075 }
    00076
    00077 static void PlaceRail_N(TileIndex tile)
    00078 {
    00079   int cmd = _tile_fract_coords.x > _tile_fract_coords.y ? 4 : 5;
    00080   GenericPlaceRail(tile, cmd);
    00081 }
    00082
    00083 static void PlaceRail_NE(TileIndex tile)
    00084 {
    00085   VpStartPlaceSizing(tile, VPM_FIX_Y, DDSP_PLACE_RAIL_NE);
    00086 }
    00087
    00088 static void PlaceRail_E(TileIndex tile)
    00089 {
    00090   int cmd = _tile_fract_coords.x + _tile_fract_coords.y <= 15 ? 2 : 3;
    00091   GenericPlaceRail(tile, cmd);
    00092 }
    00093
    00094 static void PlaceRail_NW(TileIndex tile)
    00095 {
    00096   VpStartPlaceSizing(tile, VPM_FIX_X, DDSP_PLACE_RAIL_NW);
    00097 }
    00098
    00099 static void PlaceRail_AutoRail(TileIndex tile)
    00100 {
    00101   VpStartPlaceSizing(tile, VPM_RAILDIRS, DDSP_PLACE_AUTORAIL);
    00102 }
    00103
    00110 static void PlaceExtraDepotRail(TileIndex tile, uint16 extra)
    00111 {
    00112   if (GetRailTileType(tile) != RAIL_TILE_NORMAL) return;
    00113   if ((GetTrackBits(tile) & GB(extra, 8, 8)) == 0) return;
    00114
    00115   DoCommandP(tile, _cur_railtype, extra & 0xFF, CMD_BUILD_SINGLE_RAIL);
    00116 }
    00117
    00119 static const uint16 _place_depot_extra[12] = {
    00120   0x0604, 0x2102, 0x1202, 0x0505,  // First additional track for directions 0..3
    00121   0x2400, 0x2801, 0x1800, 0x1401,  // Second additional track
    00122   0x2203, 0x0904, 0x0A05, 0x1103,  // Third additional track
    00123 };
    00124
    00125
    00126 void CcRailDepot(bool success, TileIndex tile, uint32 p1, uint32 p2)
    00127 {
    00128   if (success) {
    00129     DiagDirection dir = (DiagDirection)p2;
    00130
    00131     SndPlayTileFx(SND_20_SPLAT_2, tile);
    00132     if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
    00133
    00134     tile += TileOffsByDiagDir(dir);
    00135
    00136     if (IsTileType(tile, MP_RAILWAY)) {
    00137       PlaceExtraDepotRail(tile, _place_depot_extra[dir]);
    00138       PlaceExtraDepotRail(tile, _place_depot_extra[dir + 4]);
    00139       PlaceExtraDepotRail(tile, _place_depot_extra[dir + 8]);
    00140     }
    00141   }
    00142 }
    00143
    00144 static void PlaceRail_Depot(TileIndex tile)
    00145 {
    00146   DoCommandP(tile, _cur_railtype, _build_depot_direction,
    00147     CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_100E_CAN_T_BUILD_TRAIN_DEPOT),
    00148     CcRailDepot);
    00149 }
    00150
    00151 static void PlaceRail_Waypoint(TileIndex tile)
    00152 {
    00153   if (_remove_button_clicked) {
    00154     DoCommandP(tile, 0, 0, CMD_REMOVE_TRAIN_WAYPOINT | CMD_MSG(STR_CANT_REMOVE_TRAIN_WAYPOINT), CcPlaySound1E);
    00155   } else {
    00156     DoCommandP(tile, _cur_waypoint_type, 0, CMD_BUILD_TRAIN_WAYPOINT | CMD_MSG(STR_CANT_BUILD_TRAIN_WAYPOINT), CcPlaySound1E);
    00157   }
    00158 }
    00159
    00160 void CcStation(bool success, TileIndex tile, uint32 p1, uint32 p2)
    00161 {
    00162   if (success) {
    00163     SndPlayTileFx(SND_20_SPLAT_2, tile);
    00164     /* Only close the station builder window if the default station and non persistent building is chosen. */
    00165     if (_railstation.station_class == STAT_CLASS_DFLT && _railstation.station_type == 0 && !_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
    00166   }
    00167 }
    00168
    00169 static void PlaceRail_Station(TileIndex tile)
    00170 {
    00171   if (_remove_button_clicked) {
    00172     VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_REMOVE_STATION);
    00173     VpSetPlaceSizingLimit(-1);
    00174   } else if (_settings_client.gui.station_dragdrop) {
    00175     VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_STATION);
    00176     VpSetPlaceSizingLimit(_settings_game.station.station_spread);
    00177   } else {
    00178     uint32 p1 = _cur_railtype | _railstation.orientation << 4 | _settings_client.gui.station_numtracks << 8 | _settings_client.gui.station_platlength << 16 | _ctrl_pressed << 24;
    00179     uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16;
    00180
    00181     int w = _settings_client.gui.station_numtracks;
    00182     int h = _settings_client.gui.station_platlength;
    00183     if (!_railstation.orientation) Swap(w, h);
    00184
    00185     CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_RAILROAD_STATION | CMD_MSG(STR_100F_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" };
    00186     ShowSelectStationIfNeeded(cmdcont, w, h);
    00187   }
    00188 }
    00189
    00195 static void GenericPlaceSignals(TileIndex tile)
    00196 {
    00197   TrackBits trackbits = TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0));
    00198
    00199   if (trackbits & TRACK_BIT_VERT) { // N-S direction
    00200     trackbits = (_tile_fract_coords.x <= _tile_fract_coords.y) ? TRACK_BIT_RIGHT : TRACK_BIT_LEFT;
    00201   }
    00202
    00203   if (trackbits & TRACK_BIT_HORZ) { // E-W direction
    00204     trackbits = (_tile_fract_coords.x + _tile_fract_coords.y <= 15) ? TRACK_BIT_UPPER : TRACK_BIT_LOWER;
    00205   }
    00206
    00207   Track track = FindFirstTrack(trackbits);
    00208
    00209   if (_remove_button_clicked) {
    00210     DoCommandP(tile, track, 0, CMD_REMOVE_SIGNALS | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM), CcPlaySound1E);
    00211   } else {
    00212     const Window *w = FindWindowById(WC_BUILD_SIGNAL, 0);
    00213
    00214     /* Map the setting cycle_signal_types to the lower and upper allowed signal type. */
    00215     static const uint cycle_bounds[] = {SIGTYPE_NORMAL | (SIGTYPE_LAST_NOPBS << 3), SIGTYPE_PBS | (SIGTYPE_LAST << 3), SIGTYPE_NORMAL | (SIGTYPE_LAST << 3)};
    00216
    00217     /* various bitstuffed elements for CmdBuildSingleSignal() */
    00218     uint32 p1 = track;
    00219
    00220     if (w != NULL) {
    00221       /* signal GUI is used */
    00222       SB(p1, 3, 1, _ctrl_pressed);
    00223       SB(p1, 4, 1, _cur_signal_variant);
    00224       SB(p1, 5, 3, _cur_signal_type);
    00225       SB(p1, 8, 1, _convert_signal_button);
    00226       SB(p1, 9, 6, cycle_bounds[_settings_client.gui.cycle_signal_types]);
    00227     } else {
    00228       SB(p1, 3, 1, _ctrl_pressed);
    00229       SB(p1, 4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
    00230       SB(p1, 5, 3, _default_signal_type[_settings_client.gui.default_signal_type]);
    00231       SB(p1, 8, 1, 0);
    00232       SB(p1, 9, 6, cycle_bounds[_settings_client.gui.cycle_signal_types]);
    00233     }
    00234
    00235     DoCommandP(tile, p1, 0, CMD_BUILD_SIGNALS |
    00236       CMD_MSG((w != NULL && _convert_signal_button) ? STR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_1010_CAN_T_BUILD_SIGNALS_HERE),
    00237       CcPlaySound1E);
    00238   }
    00239 }
    00240
    00241 static void PlaceRail_Bridge(TileIndex tile)
    00242 {
    00243   VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE);
    00244 }
    00245
    00247 void CcBuildRailTunnel(bool success, TileIndex tile, uint32 p1, uint32 p2)
    00248 {
    00249   if (success) {
    00250     SndPlayTileFx(SND_20_SPLAT_2, tile);
    00251     if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
    00252   } else {
    00253     SetRedErrorSquare(_build_tunnel_endtile);
    00254   }
    00255 }
    00256
    00257 static void PlaceRail_Tunnel(TileIndex tile)
    00258 {
    00259   DoCommandP(tile, _cur_railtype, 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_5016_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel);
    00260 }
    00261
    00262 static void PlaceRail_ConvertRail(TileIndex tile)
    00263 {
    00264   VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CONVERT_RAIL);
    00265 }
    00266
    00267 static void PlaceRail_AutoSignals(TileIndex tile)
    00268 {
    00269   VpStartPlaceSizing(tile, VPM_SIGNALDIRS, DDSP_BUILD_SIGNALS);
    00270 }
    00271
    00272
    00274 enum RailToolbarWidgets {
    00275   RTW_CLOSEBOX = 0,
    00276   RTW_CAPTION,
    00277   RTW_STICKY,
    00278   RTW_SPACER,
    00279   RTW_BUILD_NS,
    00280   RTW_BUILD_X,
    00281   RTW_BUILD_EW,
    00282   RTW_BUILD_Y,
    00283   RTW_AUTORAIL,
    00284   RTW_DEMOLISH,
    00285   RTW_BUILD_DEPOT,
    00286   RTW_BUILD_WAYPOINT,
    00287   RTW_BUILD_STATION,
    00288   RTW_BUILD_SIGNALS,
    00289   RTW_BUILD_BRIDGE,
    00290   RTW_BUILD_TUNNEL,
    00291   RTW_REMOVE,
    00292   RTW_CONVERT_RAIL,
    00293 };
    00294
    00295
    00299 static void ToggleRailButton_Remove(Window *w)
    00300 {
    00301   DeleteWindowById(WC_SELECT_STATION, 0);
    00302   w->ToggleWidgetLoweredState(RTW_REMOVE);
    00303   w->InvalidateWidget(RTW_REMOVE);
    00304   _remove_button_clicked = w->IsWidgetLowered(RTW_REMOVE);
    00305   SetSelectionRed(_remove_button_clicked);
    00306 }
    00307
    00312 static bool RailToolbar_CtrlChanged(Window *w)
    00313 {
    00314   if (w->IsWidgetDisabled(RTW_REMOVE)) return false;
    00315
    00316   /* allow ctrl to switch remove mode only for these widgets */
    00317   for (uint i = RTW_BUILD_NS; i <= RTW_BUILD_STATION; i++) {
    00318     if ((i <= RTW_AUTORAIL || i >= RTW_BUILD_WAYPOINT) && w->IsWidgetLowered(i)) {
    00319       ToggleRailButton_Remove(w);
    00320       return true;
    00321     }
    00322   }
    00323
    00324   return false;
    00325 }
    00326
    00327
    00333 static void BuildRailClick_N(Window *w)
    00334 {
    00335   HandlePlacePushButton(w, RTW_BUILD_NS, GetRailTypeInfo(_cur_railtype)->cursor.rail_ns, VHM_RECT, PlaceRail_N);
    00336 }
    00337
    00343 static void BuildRailClick_NE(Window *w)
    00344 {
    00345   HandlePlacePushButton(w, RTW_BUILD_X, GetRailTypeInfo(_cur_railtype)->cursor.rail_swne, VHM_RECT, PlaceRail_NE);
    00346 }
    00347
    00353 static void BuildRailClick_E(Window *w)
    00354 {
    00355   HandlePlacePushButton(w, RTW_BUILD_EW, GetRailTypeInfo(_cur_railtype)->cursor.rail_ew, VHM_RECT, PlaceRail_E);
    00356 }
    00357
    00363 static void BuildRailClick_NW(Window *w)
    00364 {
    00365   HandlePlacePushButton(w, RTW_BUILD_Y, GetRailTypeInfo(_cur_railtype)->cursor.rail_nwse, VHM_RECT, PlaceRail_NW);
    00366 }
    00367
    00373 static void BuildRailClick_AutoRail(Window *w)
    00374 {
    00375   HandlePlacePushButton(w, RTW_AUTORAIL, GetRailTypeInfo(_cur_railtype)->cursor.autorail, VHM_RAIL, PlaceRail_AutoRail);
    00376 }
    00377
    00383 static void BuildRailClick_Demolish(Window *w)
    00384 {
    00385   HandlePlacePushButton(w, RTW_DEMOLISH, ANIMCURSOR_DEMOLISH, VHM_RECT, PlaceProc_DemolishArea);
    00386 }
    00387
    00393 static void BuildRailClick_Depot(Window *w)
    00394 {
    00395   if (HandlePlacePushButton(w, RTW_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, VHM_RECT, PlaceRail_Depot)) {
    00396     ShowBuildTrainDepotPicker(w);
    00397   }
    00398 }
    00399
    00406 static void BuildRailClick_Waypoint(Window *w)
    00407 {
    00408   _waypoint_count = GetNumCustomStations(STAT_CLASS_WAYP);
    00409   if (HandlePlacePushButton(w, RTW_BUILD_WAYPOINT, SPR_CURSOR_WAYPOINT, VHM_RECT, PlaceRail_Waypoint) &&
    00410       _waypoint_count > 1) {
    00411     ShowBuildWaypointPicker(w);
    00412   }
    00413 }
    00414
    00420 static void BuildRailClick_Station(Window *w)
    00421 {
    00422   if (HandlePlacePushButton(w, RTW_BUILD_STATION, SPR_CURSOR_RAIL_STATION, VHM_RECT, PlaceRail_Station)) ShowStationBuilder(w);
    00423 }
    00424
    00431 static void BuildRailClick_AutoSignals(Window *w)
    00432 {
    00433   if (_settings_client.gui.enable_signal_gui != _ctrl_pressed) {
    00434     if (HandlePlacePushButton(w, RTW_BUILD_SIGNALS, ANIMCURSOR_BUILDSIGNALS, VHM_RECT, PlaceRail_AutoSignals)) ShowSignalBuilder(w);
    00435   } else {
    00436     HandlePlacePushButton(w, RTW_BUILD_SIGNALS, ANIMCURSOR_BUILDSIGNALS, VHM_RECT, PlaceRail_AutoSignals);
    00437   }
    00438 }
    00439
    00445 static void BuildRailClick_Bridge(Window *w)
    00446 {
    00447   HandlePlacePushButton(w, RTW_BUILD_BRIDGE, SPR_CURSOR_BRIDGE, VHM_RECT, PlaceRail_Bridge);
    00448 }
    00449
    00455 static void BuildRailClick_Tunnel(Window *w)
    00456 {
    00457   HandlePlacePushButton(w, RTW_BUILD_TUNNEL, GetRailTypeInfo(_cur_railtype)->cursor.tunnel, VHM_SPECIAL, PlaceRail_Tunnel);
    00458 }
    00459
    00465 static void BuildRailClick_Remove(Window *w)
    00466 {
    00467   if (w->IsWidgetDisabled(RTW_REMOVE)) return;
    00468   ToggleRailButton_Remove(w);
    00469   SndPlayFx(SND_15_BEEP);
    00470
    00471   /* handle station builder */
    00472   if (w->IsWidgetLowered(RTW_BUILD_STATION)) {
    00473     if (_remove_button_clicked) {
    00474       /* starting drag & drop remove */
    00475       if (!_settings_client.gui.station_dragdrop) {
    00476         SetTileSelectSize(1, 1);
    00477       } else {
    00478         VpSetPlaceSizingLimit(-1);
    00479       }
    00480     } else {
    00481       /* starting station build mode */
    00482       if (!_settings_client.gui.station_dragdrop) {
    00483         int x = _settings_client.gui.station_numtracks;
    00484         int y = _settings_client.gui.station_platlength;
    00485         if (_railstation.orientation == 0) Swap(x, y);
    00486         SetTileSelectSize(x, y);
    00487       } else {
    00488         VpSetPlaceSizingLimit(_settings_game.station.station_spread);
    00489       }
    00490     }
    00491   }
    00492 }
    00493
    00500 static void BuildRailClick_Convert(Window *w)
    00501 {
    00502   HandlePlacePushButton(w, RTW_CONVERT_RAIL, GetRailTypeInfo(_cur_railtype)->cursor.convert, VHM_RECT, PlaceRail_ConvertRail);
    00503 }
    00504
    00505
    00506 static void DoRailroadTrack(int mode)
    00507 {
    00508   DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 4),
    00509     _remove_button_clicked ?
    00510     CMD_REMOVE_RAILROAD_TRACK | CMD_MSG(STR_1012_CAN_T_REMOVE_RAILROAD_TRACK) :
    00511     CMD_BUILD_RAILROAD_TRACK  | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK)
    00512   );
    00513 }
    00514
    00515 static void HandleAutodirPlacement()
    00516 {
    00517   TileHighlightData *thd = &_thd;
    00518   int trackstat = thd->drawstyle & 0xF; // 0..5
    00519
    00520   if (thd->drawstyle & HT_RAIL) { // one tile case
    00521     GenericPlaceRail(TileVirtXY(thd->selend.x, thd->selend.y), trackstat);
    00522     return;
    00523   }
    00524
    00525   DoRailroadTrack(trackstat);
    00526 }
    00527
    00534 static void HandleAutoSignalPlacement()
    00535 {
    00536   TileHighlightData *thd = &_thd;
    00537   uint32 p2 = GB(thd->drawstyle, 0, 3); // 0..5
    00538
    00539   if (thd->drawstyle == HT_RECT) { // one tile case
    00540     GenericPlaceSignals(TileVirtXY(thd->selend.x, thd->selend.y));
    00541     return;
    00542   }
    00543
    00544   const Window *w = FindWindowById(WC_BUILD_SIGNAL, 0);
    00545
    00546   if (w != NULL) {
    00547     /* signal GUI is used */
    00548     SB(p2,  3, 1, 0);
    00549     SB(p2,  4, 1, _cur_signal_variant);
    00550     SB(p2,  6, 1, _ctrl_pressed);
    00551     SB(p2,  7, 3, _cur_signal_type);
    00552     SB(p2, 24, 8, _settings_client.gui.drag_signals_density);
    00553   } else {
    00554     SB(p2,  3, 1, 0);
    00555     SB(p2,  4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
    00556     SB(p2,  6, 1, _ctrl_pressed);
    00557     SB(p2,  7, 3, _default_signal_type[_settings_client.gui.default_signal_type]);
    00558     SB(p2, 24, 8, _settings_client.gui.drag_signals_density);
    00559   }
    00560
    00561   /* _settings_client.gui.drag_signals_density is given as a parameter such that each user
    00562    * in a network game can specify his/her own signal density */
    00563   DoCommandP(
    00564     TileVirtXY(thd->selstart.x, thd->selstart.y),
    00565     TileVirtXY(thd->selend.x, thd->selend.y),
    00566     p2,
    00567     _remove_button_clicked ?
    00568       CMD_REMOVE_SIGNAL_TRACK | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM) :
    00569       CMD_BUILD_SIGNAL_TRACK  | CMD_MSG(STR_1010_CAN_T_BUILD_SIGNALS_HERE),
    00570     CcPlaySound1E);
    00571 }
    00572
    00573
    00574 typedef void OnButtonClick(Window *w);
    00575
    00577 struct RailBuildingGUIButtonData {
    00578   uint16 keycode;
    00579   OnButtonClick *click_proc;
    00580 };
    00581
    00586 static const RailBuildingGUIButtonData _rail_build_button_data[] = {
    00587   {'1', BuildRailClick_N          },
    00588   {'2', BuildRailClick_NE         },
    00589   {'3', BuildRailClick_E          },
    00590   {'4', BuildRailClick_NW         },
    00591   {'5', BuildRailClick_AutoRail   },
    00592   {'6', BuildRailClick_Demolish   },
    00593   {'7', BuildRailClick_Depot      },
    00594   {'8', BuildRailClick_Waypoint   },
    00595   {'9', BuildRailClick_Station    },
    00596   {'S', BuildRailClick_AutoSignals},
    00597   {'B', BuildRailClick_Bridge     },
    00598   {'T', BuildRailClick_Tunnel     },
    00599   {'R', BuildRailClick_Remove     },
    00600   {'C', BuildRailClick_Convert    }
    00601 };
    00602
    00608 struct BuildRailToolbarWindow : Window {
    00609   BuildRailToolbarWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
    00610   {
    00611     this->DisableWidget(RTW_REMOVE);
    00612
    00613     this->FindWindowPlacementAndResize(desc);
    00614     if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
    00615   }
    00616
    00617   ~BuildRailToolbarWindow()
    00618   {
    00619     if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false);
    00620   }
    00621
    00622   void UpdateRemoveWidgetStatus(int clicked_widget)
    00623   {
    00624     switch (clicked_widget) {
    00625       case RTW_REMOVE:
    00626         /* If it is the removal button that has been clicked, do nothing,
    00627          * as it is up to the other buttons to drive removal status */
    00628         return;
    00629         break;
    00630       case RTW_BUILD_NS:
    00631       case RTW_BUILD_X:
    00632       case RTW_BUILD_EW:
    00633       case RTW_BUILD_Y:
    00634       case RTW_AUTORAIL:
    00635       case RTW_BUILD_WAYPOINT:
    00636       case RTW_BUILD_STATION:
    00637       case RTW_BUILD_SIGNALS:
    00638         /* Removal button is enabled only if the rail/signal/waypoint/station
    00639          * button is still lowered.  Once raised, it has to be disabled */
    00640         this->SetWidgetDisabledState(RTW_REMOVE, !this->IsWidgetLowered(clicked_widget));
    00641         break;
    00642
    00643       default:
    00644         /* When any other buttons than rail/signal/waypoint/station, raise and
    00645          * disable the removal button */
    00646         this->DisableWidget(RTW_REMOVE);
    00647         this->RaiseWidget(RTW_REMOVE);
    00648         break;
    00649     }
    00650   }
    00651
    00652   virtual void OnPaint()
    00653   {
    00654     this->DrawWidgets();
    00655   }
    00656
    00657   virtual void OnClick(Point pt, int widget)
    00658   {
    00659     if (widget >= RTW_BUILD_NS) {
    00660       _remove_button_clicked = false;
    00661       _rail_build_button_data[widget - RTW_BUILD_NS].click_proc(this);
    00662     }
    00663     this->UpdateRemoveWidgetStatus(widget);
    00664     if (_ctrl_pressed) RailToolbar_CtrlChanged(this);
    00665   }
    00666
    00667   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
    00668   {
    00669     EventState state = ES_NOT_HANDLED;
    00670     for (uint8 i = 0; i != lengthof(_rail_build_button_data); i++) {
    00671       if (keycode == _rail_build_button_data[i].keycode) {
    00672         _remove_button_clicked = false;
    00673         _rail_build_button_data[i].click_proc(this);
    00674         this->UpdateRemoveWidgetStatus(i + RTW_BUILD_NS);
    00675         if (_ctrl_pressed) RailToolbar_CtrlChanged(this);
    00676         state = ES_HANDLED;
    00677         break;
    00678       }
    00679     }
    00680     MarkTileDirty(_thd.pos.x, _thd.pos.y); // redraw tile selection
    00681     return state;
    00682   }
    00683
    00684   virtual void OnPlaceObject(Point pt, TileIndex tile)
    00685   {
    00686     _place_proc(tile);
    00687   }
    00688
    00689   virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
    00690   {
    00691     /* no dragging if you have pressed the convert button */
    00692     if (FindWindowById(WC_BUILD_SIGNAL, 0) != NULL && _convert_signal_button && this->IsWidgetLowered(RTW_BUILD_SIGNALS)) return;
    00693
    00694     VpSelectTilesWithMethod(pt.x, pt.y, select_method);
    00695   }
    00696
    00697   virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
    00698   {
    00699     if (pt.x != -1) {
    00700       switch (select_proc) {
    00701         default: NOT_REACHED();
    00702         case DDSP_BUILD_BRIDGE:
    00703           if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
    00704           ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_RAIL, _cur_railtype);
    00705           break;
    00706
    00707         case DDSP_PLACE_AUTORAIL:
    00708           HandleAutodirPlacement();
    00709           break;
    00710
    00711         case DDSP_BUILD_SIGNALS:
    00712           HandleAutoSignalPlacement();
    00713           break;
    00714
    00715         case DDSP_DEMOLISH_AREA:
    00716           GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
    00717           break;
    00718
    00719         case DDSP_CONVERT_RAIL:
    00720           DoCommandP(end_tile, start_tile, _cur_railtype, CMD_CONVERT_RAIL | CMD_MSG(STR_CANT_CONVERT_RAIL), CcPlaySound10);
    00721           break;
    00722
    00723         case DDSP_REMOVE_STATION:
    00724         case DDSP_BUILD_STATION:
    00725           if (_remove_button_clicked) {
    00726             DoCommandP(end_tile, start_tile, 0, CMD_REMOVE_FROM_RAILROAD_STATION | CMD_MSG(STR_CANT_REMOVE_PART_OF_STATION), CcPlaySound1E);
    00727             break;
    00728           }
    00729           HandleStationPlacement(start_tile, end_tile);
    00730           break;
    00731
    00732         case DDSP_PLACE_RAIL_NE:
    00733         case DDSP_PLACE_RAIL_NW:
    00734           DoRailroadTrack(select_proc == DDSP_PLACE_RAIL_NE ? TRACK_X : TRACK_Y);
    00735           break;
    00736       }
    00737     }
    00738   }
    00739
    00740   virtual void OnPlaceObjectAbort()
    00741   {
    00742     this->RaiseButtons();
    00743     this->DisableWidget(RTW_REMOVE);
    00744     this->InvalidateWidget(RTW_REMOVE);
    00745
    00746     DeleteWindowById(WC_BUILD_SIGNAL, 0);
    00747     DeleteWindowById(WC_BUILD_STATION, 0);
    00748     DeleteWindowById(WC_BUILD_DEPOT, 0);
    00749     DeleteWindowById(WC_SELECT_STATION, 0);
    00750     DeleteWindowById(WC_BUILD_BRIDGE, 0);
    00751   }
    00752
    00753   virtual void OnPlacePresize(Point pt, TileIndex tile)
    00754   {
    00755     DoCommand(tile, 0, 0, DC_AUTO, CMD_BUILD_TUNNEL);
    00756     VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
    00757   }
    00758
    00759   virtual EventState OnCTRLStateChange()
    00760   {
    00761     /* do not toggle Remove button by Ctrl when placing station */
    00762     if (!this->IsWidgetLowered(RTW_BUILD_STATION) && RailToolbar_CtrlChanged(this)) return ES_HANDLED;
    00763     return ES_NOT_HANDLED;
    00764   }
    00765 };
    00766
    00768 static const Widget _build_rail_widgets[] = {
    00769 {   WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN,     0,    10,     0,    13, STR_00C5,                       STR_018B_CLOSE_WINDOW},                   // RTW_CLOSEBOX
    00770 {    WWT_CAPTION,   RESIZE_NONE,  COLOUR_DARK_GREEN,    11,   337,     0,    13, STR_100A_RAILROAD_CONSTRUCTION, STR_018C_WINDOW_TITLE_DRAG_THIS},         // RTW_CAPTION
    00771 {  WWT_STICKYBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN,   338,   349,     0,    13, 0x0,                            STR_STICKY_BUTTON},                       // RTW_STICKY
    00772
    00773 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   110,   113,    14,    35, 0x0,                            STR_NULL},                                // RTW_SPACER
    00774
    00775 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,     0,    21,    14,    35, SPR_IMG_RAIL_NS,                STR_1018_BUILD_RAILROAD_TRACK},           // RTW_BUILD_NS
    00776 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,    22,    43,    14,    35, SPR_IMG_RAIL_NE,                STR_1018_BUILD_RAILROAD_TRACK},           // RTW_BUILD_X
    00777 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,    44,    65,    14,    35, SPR_IMG_RAIL_EW,                STR_1018_BUILD_RAILROAD_TRACK},           // RTW_BUILD_EW
    00778 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,    66,    87,    14,    35, SPR_IMG_RAIL_NW,                STR_1018_BUILD_RAILROAD_TRACK},           // RTW_BUILD_Y
    00779 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,    88,   109,    14,    35, SPR_IMG_AUTORAIL,               STR_BUILD_AUTORAIL_TIP},                  // RTW_AUTORAIL
    00780
    00781 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,   114,   135,    14,    35, SPR_IMG_DYNAMITE,               STR_018D_DEMOLISH_BUILDINGS_ETC},         // RTW_DEMOLISH
    00782 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,   136,   157,    14,    35, SPR_IMG_DEPOT_RAIL,             STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING}, // RTW_BUILD_DEPOT
    00783 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,   158,   179,    14,    35, SPR_IMG_WAYPOINT,               STR_CONVERT_RAIL_TO_WAYPOINT_TIP},        // RTW_BUILD_WAYPOINT
    00784
    00785 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,   180,   221,    14,    35, SPR_IMG_RAIL_STATION,           STR_101A_BUILD_RAILROAD_STATION},         // RTW_BUILD_STATION
    00786 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,   222,   243,    14,    35, SPR_IMG_RAIL_SIGNALS,           STR_101B_BUILD_RAILROAD_SIGNALS},         // RTW_BUILD_SIGNALS
    00787 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,   244,   285,    14,    35, SPR_IMG_BRIDGE,                 STR_101C_BUILD_RAILROAD_BRIDGE},          // RTW_BUILD_BRIDGE
    00788 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,   286,   305,    14,    35, SPR_IMG_TUNNEL_RAIL,            STR_101D_BUILD_RAILROAD_TUNNEL},          // RTW_BUILD_TUNNEL
    00789 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,   306,   327,    14,    35, SPR_IMG_REMOVE,                 STR_101E_TOGGLE_BUILD_REMOVE_FOR},        // RTW_REMOVE
    00790 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,   328,   349,    14,    35, SPR_IMG_CONVERT_RAIL,           STR_CONVERT_RAIL_TIP},                    // RTW_CONVERT_RAIL
    00791
    00792 {   WIDGETS_END},
    00793 };
    00794
    00795 static const WindowDesc _build_rail_desc(
    00796   WDP_ALIGN_TBR, 22, 350, 36, 350, 36,
    00797   WC_BUILD_TOOLBAR, WC_NONE,
    00798   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON | WDF_CONSTRUCTION,
    00799   _build_rail_widgets
    00800 );
    00801
    00802
    00807 static void SetupRailToolbar(RailType railtype, Window *w)
    00808 {
    00809   const RailtypeInfo *rti = GetRailTypeInfo(railtype);
    00810
    00811   assert(railtype < RAILTYPE_END);
    00812   w->widget[RTW_CAPTION].data = rti->strings.toolbar_caption;
    00813   w->widget[RTW_BUILD_NS].data = rti->gui_sprites.build_ns_rail;
    00814   w->widget[RTW_BUILD_X].data = rti->gui_sprites.build_x_rail;
    00815   w->widget[RTW_BUILD_EW].data = rti->gui_sprites.build_ew_rail;
    00816   w->widget[RTW_BUILD_Y].data = rti->gui_sprites.build_y_rail;
    00817   w->widget[RTW_AUTORAIL].data = rti->gui_sprites.auto_rail;
    00818   w->widget[RTW_BUILD_DEPOT].data = rti->gui_sprites.build_depot;
    00819   w->widget[RTW_CONVERT_RAIL].data = rti->gui_sprites.convert_rail;
    00820   w->widget[RTW_BUILD_TUNNEL].data = rti->gui_sprites.build_tunnel;
    00821 }
    00822
    00834 void ShowBuildRailToolbar(RailType railtype, int button)
    00835 {
    00836   BuildRailToolbarWindow *w;
    00837
    00838   if (!IsValidCompanyID(_local_company)) return;
    00839   if (!ValParamRailtype(railtype)) return;
    00840
    00841   /* don't recreate the window if we're clicking on a button and the window exists. */
    00842   if (button < 0 || !(w = dynamic_cast<BuildRailToolbarWindow*>(FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_RAIL)))) {
    00843     DeleteWindowByClass(WC_BUILD_TOOLBAR);
    00844     _cur_railtype = railtype;
    00845     w = AllocateWindowDescFront<BuildRailToolbarWindow>(&_build_rail_desc, TRANSPORT_RAIL);
    00846     SetupRailToolbar(railtype, w);
    00847   }
    00848
    00849   _remove_button_clicked = false;
    00850   if (w != NULL && button >= RTW_CLOSEBOX) {
    00851     _rail_build_button_data[button].click_proc(w);
    00852     w->UpdateRemoveWidgetStatus(button + RTW_BUILD_NS);
    00853   }
    00854 }
    00855
    00856 /* TODO: For custom stations, respect their allowed platforms/lengths bitmasks!
    00857  * --pasky */
    00858
    00859 static void HandleStationPlacement(TileIndex start, TileIndex end)
    00860 {
    00861   uint sx = TileX(start);
    00862   uint sy = TileY(start);
    00863   uint ex = TileX(end);
    00864   uint ey = TileY(end);
    00865   uint w, h;
    00866
    00867   if (sx > ex) Swap(sx, ex);
    00868   if (sy > ey) Swap(sy, ey);
    00869   w = ex - sx + 1;
    00870   h = ey - sy + 1;
    00871
    00872   uint numtracks = w;
    00873   uint platlength = h;
    00874   if (_railstation.orientation == AXIS_X) Swap(numtracks, platlength);
    00875
    00876   uint32 p1 = _cur_railtype | _railstation.orientation << 4 | _ctrl_pressed << 24;
    00877   uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16;
    00878
    00879   CommandContainer cmdcont = { TileXY(sx, sy), p1 | numtracks << 8 | platlength << 16, p2, CMD_BUILD_RAILROAD_STATION | CMD_MSG(STR_100F_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" };
    00880   ShowSelectStationIfNeeded(cmdcont, w, h);
    00881 }
    00882
    00883 struct BuildRailStationWindow : public PickerWindowBase {
    00884 private:
    00886   enum BuildRailStationWidgets {
    00887     BRSW_CLOSEBOX = 0,
    00888     BRSW_CAPTION,
    00889     BRSW_BACKGROUND,
    00890
    00891     BRSW_PLATFORM_DIR_X,
    00892     BRSW_PLATFORM_DIR_Y,
    00893
    00894     BRSW_PLATFORM_NUM_BEGIN = BRSW_PLATFORM_DIR_Y,
    00895     BRSW_PLATFORM_NUM_1,
    00896     BRSW_PLATFORM_NUM_2,
    00897     BRSW_PLATFORM_NUM_3,
    00898     BRSW_PLATFORM_NUM_4,
    00899     BRSW_PLATFORM_NUM_5,
    00900     BRSW_PLATFORM_NUM_6,
    00901     BRSW_PLATFORM_NUM_7,
    00902
    00903     BRSW_PLATFORM_LEN_BEGIN = BRSW_PLATFORM_NUM_7,
    00904     BRSW_PLATFORM_LEN_1,
    00905     BRSW_PLATFORM_LEN_2,
    00906     BRSW_PLATFORM_LEN_3,
    00907     BRSW_PLATFORM_LEN_4,
    00908     BRSW_PLATFORM_LEN_5,
    00909     BRSW_PLATFORM_LEN_6,
    00910     BRSW_PLATFORM_LEN_7,
    00911
    00912     BRSW_PLATFORM_DRAG_N_DROP,
    00913
    00914     BRSW_HIGHLIGHT_OFF,
    00915     BRSW_HIGHLIGHT_ON,
    00916
    00917     BRSW_NEWST_DROPDOWN,
    00918     BRSW_NEWST_LIST,
    00919     BRSW_NEWST_SCROLL
    00920   };
    00921
    00927   void CheckSelectedSize(const StationSpec *statspec)
    00928   {
    00929     if (statspec == NULL || _settings_client.gui.station_dragdrop) return;
    00930
    00931     /* If current number of tracks is not allowed, make it as big as possible (which is always less than currently selected) */
    00932     if (HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
    00933       this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
    00934       _settings_client.gui.station_numtracks = 1;
    00935       while (HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
    00936         _settings_client.gui.station_numtracks++;
    00937       }
    00938       this->LowerWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
    00939     }
    00940
    00941     if (HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
    00942       this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
    00943       _settings_client.gui.station_platlength = 1;
    00944       while (HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
    00945         _settings_client.gui.station_platlength++;
    00946       }
    00947       this->LowerWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
    00948     }
    00949   }
    00950
    00952   static DropDownList *BuildStationClassDropDown()
    00953   {
    00954     DropDownList *list = new DropDownList();
    00955
    00956     for (uint i = 0; i < GetNumStationClasses(); i++) {
    00957       if (i == STAT_CLASS_WAYP) continue;
    00958       list->push_back(new DropDownListStringItem(GetStationClassName((StationClassID)i), i, false));
    00959     }
    00960
    00961     return list;
    00962   }
    00969 public:
    00970   BuildRailStationWindow(const WindowDesc *desc, Window *parent, bool newstation) : PickerWindowBase(desc, parent)
    00971   {
    00972     this->LowerWidget(_railstation.orientation + BRSW_PLATFORM_DIR_X);
    00973     if (_settings_client.gui.station_dragdrop) {
    00974       this->LowerWidget(BRSW_PLATFORM_DRAG_N_DROP);
    00975     } else {
    00976       this->LowerWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
    00977       this->LowerWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
    00978     }
    00979     this->SetWidgetLoweredState(BRSW_HIGHLIGHT_OFF, !_settings_client.gui.station_show_coverage);
    00980     this->SetWidgetLoweredState(BRSW_HIGHLIGHT_ON, _settings_client.gui.station_show_coverage);
    00981
    00982     this->FindWindowPlacementAndResize(desc);
    00983
    00984     _railstation.newstations = newstation;
    00985
    00986     if (newstation) {
    00987       _railstation.station_count = GetNumCustomStations(_railstation.station_class);
    00988
    00989       this->vscroll.count = _railstation.station_count;
    00990       this->vscroll.cap   = 5;
    00991       this->vscroll.pos   = Clamp(_railstation.station_type - 2, 0, this->vscroll.count - this->vscroll.cap);
    00992     } else {
    00993       /* New stations are not available, so ensure the default station
    00994        * type is 'selected'. */
    00995       _railstation.station_class = STAT_CLASS_DFLT;
    00996       _railstation.station_type = 0;
    00997     }
    00998   }
    00999
    01000   virtual ~BuildRailStationWindow()
    01001   {
    01002     DeleteWindowById(WC_SELECT_STATION, 0);
    01003   }
    01004
    01005   virtual void OnPaint()
    01006   {
    01007     bool newstations = _railstation.newstations;
    01008     DrawPixelInfo tmp_dpi, *old_dpi;
    01009     const StationSpec *statspec = newstations ? GetCustomStationSpec(_railstation.station_class, _railstation.station_type) : NULL;
    01010
    01011     if (_settings_client.gui.station_dragdrop) {
    01012       SetTileSelectSize(1, 1);
    01013     } else {
    01014       int x = _settings_client.gui.station_numtracks;
    01015       int y = _settings_client.gui.station_platlength;
    01016       if (_railstation.orientation == AXIS_X) Swap(x, y);
    01017       if (!_remove_button_clicked)
    01018         SetTileSelectSize(x, y);
    01019     }
    01020
    01021     int rad = (_settings_game.station.modified_catchment) ? CA_TRAIN : CA_UNMODIFIED;
    01022
    01023     if (_settings_client.gui.station_show_coverage)
    01024       SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
    01025
    01026     for (uint bits = 0; bits < 7; bits++) {
    01027       bool disable = bits >= _settings_game.station.station_spread;
    01028       if (statspec == NULL) {
    01029         this->SetWidgetDisabledState(bits + BRSW_PLATFORM_NUM_1, disable);
    01030         this->SetWidgetDisabledState(bits + BRSW_PLATFORM_LEN_1, disable);
    01031       } else {
    01032         this->SetWidgetDisabledState(bits + BRSW_PLATFORM_NUM_1, HasBit(statspec->disallowed_platforms, bits) || disable);
    01033         this->SetWidgetDisabledState(bits + BRSW_PLATFORM_LEN_1, HasBit(statspec->disallowed_lengths,   bits) || disable);
    01034       }
    01035     }
    01036
    01037     SetDParam(0, GetStationClassName(_railstation.station_class));
    01038     this->DrawWidgets();
    01039
    01040     int y_offset = newstations ? 90 : 0;
    01041
    01042     /* Set up a clipping area for the '/' station preview */
    01043     if (FillDrawPixelInfo(&tmp_dpi, 7, 26 + y_offset, 66, 48)) {
    01044       old_dpi = _cur_dpi;
    01045       _cur_dpi = &tmp_dpi;
    01046       if (!DrawStationTile(32, 16, _cur_railtype, AXIS_X, _railstation.station_class, _railstation.station_type)) {
    01047         StationPickerDrawSprite(32, 16, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2);
    01048       }
    01049       _cur_dpi = old_dpi;
    01050     }
    01051
    01052     /* Set up a clipping area for the '\' station preview */
    01053     if (FillDrawPixelInfo(&tmp_dpi, 75, 26 + y_offset, 66, 48)) {
    01054       old_dpi = _cur_dpi;
    01055       _cur_dpi = &tmp_dpi;
    01056       if (!DrawStationTile(32, 16, _cur_railtype, AXIS_Y, _railstation.station_class, _railstation.station_type)) {
    01057         StationPickerDrawSprite(32, 16, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 3);
    01058       }
    01059       _cur_dpi = old_dpi;
    01060     }
    01061
    01062     DrawStringCentered(74, 15 + y_offset, STR_3002_ORIENTATION, TC_FROMSTRING);
    01063     DrawStringCentered(74, 76 + y_offset, STR_3003_NUMBER_OF_TRACKS, TC_FROMSTRING);
    01064     DrawStringCentered(74, 101 + y_offset, STR_3004_PLATFORM_LENGTH, TC_FROMSTRING);
    01065     DrawStringCentered(74, 141 + y_offset, STR_3066_COVERAGE_AREA_HIGHLIGHT, TC_FROMSTRING);
    01066
    01067     int text_end = DrawStationCoverageAreaText(2, 166 + y_offset, SCT_ALL, rad, false);
    01068     text_end = DrawStationCoverageAreaText(2, text_end + 4, SCT_ALL, rad, true) + 4;
    01069     if (text_end != this->widget[BRSW_BACKGROUND].bottom) {
    01070       this->SetDirty();
    01071       ResizeWindowForWidget(this, BRSW_BACKGROUND, 0, text_end - this->widget[BRSW_BACKGROUND].bottom);
    01072       this->SetDirty();
    01073     }
    01074
    01075     if (newstations) {
    01076       uint y = 35;
    01077
    01078       for (uint16 i = this->vscroll.pos; i < _railstation.station_count && i < (uint)(this->vscroll.pos + this->vscroll.cap); i++) {
    01079         const StationSpec *statspec = GetCustomStationSpec(_railstation.station_class, i);
    01080
    01081         if (statspec != NULL && statspec->name != 0) {
    01082           if (HasBit(statspec->callbackmask, CBM_STATION_AVAIL) && GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) {
    01083             GfxFillRect(8, y - 2, 127, y + 10, 0, FILLRECT_CHECKER);
    01084           }
    01085
    01086           DrawStringTruncated(9, y, statspec->name, i == _railstation.station_type ? TC_WHITE : TC_BLACK, 118);
    01087         } else {
    01088           DrawStringTruncated(9, y, STR_STAT_CLASS_DFLT, i == _railstation.station_type ? TC_WHITE : TC_BLACK, 118);
    01089         }
    01090
    01091         y += 14;
    01092       }
    01093     }
    01094   }
    01095
    01096   virtual void OnClick(Point pt, int widget)
    01097   {
    01098     switch (widget) {
    01099       case BRSW_PLATFORM_DIR_X:
    01100       case BRSW_PLATFORM_DIR_Y:
    01101         this->RaiseWidget(_railstation.orientation + BRSW_PLATFORM_DIR_X);
    01102         _railstation.orientation = (Axis)(widget - BRSW_PLATFORM_DIR_X);
    01103         this->LowerWidget(_railstation.orientation + BRSW_PLATFORM_DIR_X);
    01104         SndPlayFx(SND_15_BEEP);
    01105         this->SetDirty();
    01106         DeleteWindowById(WC_SELECT_STATION, 0);
    01107         break;
    01108
    01109       case BRSW_PLATFORM_NUM_1:
    01110       case BRSW_PLATFORM_NUM_2:
    01111       case BRSW_PLATFORM_NUM_3:
    01112       case BRSW_PLATFORM_NUM_4:
    01113       case BRSW_PLATFORM_NUM_5:
    01114       case BRSW_PLATFORM_NUM_6:
    01115       case BRSW_PLATFORM_NUM_7: {
    01116         this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
    01117         this->RaiseWidget(BRSW_PLATFORM_DRAG_N_DROP);
    01118
    01119         _settings_client.gui.station_numtracks = widget - BRSW_PLATFORM_NUM_BEGIN;
    01120         _settings_client.gui.station_dragdrop = false;
    01121
    01122         _settings_client.gui.station_dragdrop = false;
    01123
    01124         const StationSpec *statspec = _railstation.newstations ? GetCustomStationSpec(_railstation.station_class, _railstation.station_type) : NULL;
    01125         if (statspec != NULL && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
    01126           /* The previously selected number of platforms in invalid */
    01127           for (uint i = 0; i < 7; i++) {
    01128             if (!HasBit(statspec->disallowed_lengths, i)) {
    01129               this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
    01130               _settings_client.gui.station_platlength = i + 1;
    01131               break;
    01132             }
    01133           }
    01134         }
    01135
    01136         this->LowerWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
    01137         this->LowerWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
    01138         SndPlayFx(SND_15_BEEP);
    01139         this->SetDirty();
    01140         DeleteWindowById(WC_SELECT_STATION, 0);
    01141         break;
    01142       }
    01143
    01144       case BRSW_PLATFORM_LEN_1:
    01145       case BRSW_PLATFORM_LEN_2:
    01146       case BRSW_PLATFORM_LEN_3:
    01147       case BRSW_PLATFORM_LEN_4:
    01148       case BRSW_PLATFORM_LEN_5:
    01149       case BRSW_PLATFORM_LEN_6:
    01150       case BRSW_PLATFORM_LEN_7: {
    01151         this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
    01152         this->RaiseWidget(BRSW_PLATFORM_DRAG_N_DROP);
    01153
    01154         _settings_client.gui.station_platlength = widget - BRSW_PLATFORM_LEN_BEGIN;
    01155         _settings_client.gui.station_dragdrop = false;
    01156
    01157         _settings_client.gui.station_dragdrop = false;
    01158
    01159         const StationSpec *statspec = _railstation.newstations ? GetCustomStationSpec(_railstation.station_class, _railstation.station_type) : NULL;
    01160         if (statspec != NULL && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
    01161           /* The previously selected number of tracks in invalid */
    01162           for (uint i = 0; i < 7; i++) {
    01163             if (!HasBit(statspec->disallowed_platforms, i)) {
    01164               this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
    01165               _settings_client.gui.station_numtracks = i + 1;
    01166               break;
    01167             }
    01168           }
    01169         }
    01170
    01171         this->LowerWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
    01172         this->LowerWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
    01173         SndPlayFx(SND_15_BEEP);
    01174         this->SetDirty();
    01175         DeleteWindowById(WC_SELECT_STATION, 0);
    01176         break;
    01177       }
    01178
    01179       case BRSW_PLATFORM_DRAG_N_DROP: {
    01180         _settings_client.gui.station_dragdrop ^= true;
    01181
    01182         this->ToggleWidgetLoweredState(BRSW_PLATFORM_DRAG_N_DROP);
    01183
    01184         /* get the first allowed length/number of platforms */
    01185         const StationSpec *statspec = _railstation.newstations ? GetCustomStationSpec(_railstation.station_class, _railstation.station_type) : NULL;
    01186         if (statspec != NULL && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
    01187           for (uint i = 0; i < 7; i++) {
    01188             if (!HasBit(statspec->disallowed_lengths, i)) {
    01189               this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
    01190               _settings_client.gui.station_platlength = i + 1;
    01191               break;
    01192             }
    01193           }
    01194         }
    01195         if (statspec != NULL && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
    01196           for (uint i = 0; i < 7; i++) {
    01197             if (!HasBit(statspec->disallowed_platforms, i)) {
    01198               this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
    01199               _settings_client.gui.station_numtracks = i + 1;
    01200               break;
    01201             }
    01202           }
    01203         }
    01204
    01205         this->SetWidgetLoweredState(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN, !_settings_client.gui.station_dragdrop);
    01206         this->SetWidgetLoweredState(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN, !_settings_client.gui.station_dragdrop);
    01207         SndPlayFx(SND_15_BEEP);
    01208         this->SetDirty();
    01209         DeleteWindowById(WC_SELECT_STATION, 0);
    01210       } break;
    01211
    01212       case BRSW_HIGHLIGHT_OFF:
    01213       case BRSW_HIGHLIGHT_ON:
    01214         _settings_client.gui.station_show_coverage = (widget != BRSW_HIGHLIGHT_OFF);
    01215
    01216         this->SetWidgetLoweredState(BRSW_HIGHLIGHT_OFF, !_settings_client.gui.station_show_coverage);
    01217         this->SetWidgetLoweredState(BRSW_HIGHLIGHT_ON, _settings_client.gui.station_show_coverage);
    01218         SndPlayFx(SND_15_BEEP);
    01219         this->SetDirty();
    01220         break;
    01221
    01222       case BRSW_NEWST_DROPDOWN:
    01223         ShowDropDownList(this, BuildStationClassDropDown(), _railstation.station_class, BRSW_NEWST_DROPDOWN);
    01224         break;
    01225
    01226       case BRSW_NEWST_LIST: {
    01227         const StationSpec *statspec;
    01228         int y = (pt.y - 32) / 14;
    01229
    01230         if (y >= this->vscroll.cap) return;
    01231         y += this->vscroll.pos;
    01232         if (y >= _railstation.station_count) return;
    01233
    01234         /* Check station availability callback */
    01235         statspec = GetCustomStationSpec(_railstation.station_class, y);
    01236         if (statspec != NULL &&
    01237           HasBit(statspec->callbackmask, CBM_STATION_AVAIL) &&
    01238           GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) return;
    01239
    01240         _railstation.station_type = y;
    01241
    01242         this->CheckSelectedSize(statspec);
    01243
    01244         SndPlayFx(SND_15_BEEP);
    01245         this->SetDirty();
    01246         DeleteWindowById(WC_SELECT_STATION, 0);
    01247         break;
    01248       }
    01249     }
    01250   }
    01251
    01252   virtual void OnDropdownSelect(int widget, int index)
    01253   {
    01254     if (_railstation.station_class != index) {
    01255       _railstation.station_class = (StationClassID)index;
    01256       _railstation.station_type  = 0;
    01257       _railstation.station_count = GetNumCustomStations(_railstation.station_class);
    01258
    01259       this->CheckSelectedSize(GetCustomStationSpec(_railstation.station_class, _railstation.station_type));
    01260
    01261       this->vscroll.count = _railstation.station_count;
    01262       this->vscroll.pos   = _railstation.station_type;
    01263     }
    01264
    01265     SndPlayFx(SND_15_BEEP);
    01266     this->SetDirty();
    01267     DeleteWindowById(WC_SELECT_STATION, 0);
    01268   }
    01269
    01270   virtual void OnTick()
    01271   {
    01272     CheckRedrawStationCoverage(this);
    01273   }
    01274 };
    01275
    01277 static const Widget _station_builder_widgets[] = {
    01278 {   WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,    10,     0,    13, STR_00C5,                        STR_018B_CLOSE_WINDOW},               // BRSW_CLOSEBOX
    01279 {    WWT_CAPTION,   RESIZE_NONE,  COLOUR_DARK_GREEN,  11,   147,     0,    13, STR_3000_RAIL_STATION_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS},     // BRSW_CAPTION
    01280 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,   147,    14,   199, 0x0,                             STR_NULL},                            // BRSW_BACKGROUND
    01281 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,         7,    72,    26,    73, 0x0,                             STR_304E_SELECT_RAILROAD_STATION},    // BRSW_PLATFORM_DIR_X
    01282 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,        75,   140,    26,    73, 0x0,                             STR_304E_SELECT_RAILROAD_STATION},    // BRSW_PLATFORM_DIR_Y
    01283
    01284 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        22,    36,    87,    98, STR_00CB_1,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_1
    01285 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        37,    51,    87,    98, STR_00CC_2,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_2
    01286 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        52,    66,    87,    98, STR_00CD_3,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_3
    01287 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        67,    81,    87,    98, STR_00CE_4,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_4
    01288 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        82,    96,    87,    98, STR_00CF_5,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_5
    01289 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        97,   111,    87,    98, STR_6,                           STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_6
    01290 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,       112,   126,    87,    98, STR_7,                           STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_7
    01291
    01292 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        22,    36,   112,   123, STR_00CB_1,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_1
    01293 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        37,    51,   112,   123, STR_00CC_2,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_2
    01294 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        52,    66,   112,   123, STR_00CD_3,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_3
    01295 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        67,    81,   112,   123, STR_00CE_4,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_4
    01296 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        82,    96,   112,   123, STR_00CF_5,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_5
    01297 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        97,   111,   112,   123, STR_6,                           STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_6
    01298 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,       112,   126,   112,   123, STR_7,                           STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_7
    01299
    01300 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        37,   111,   126,   137, STR_DRAG_DROP,                   STR_STATION_DRAG_DROP},               // BRSW_PLATFORM_DRAG_N_DROP
    01301 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        14,    73,   152,   163, STR_02DB_OFF,                    STR_3065_DON_T_HIGHLIGHT_COVERAGE},   // BRSW_HIGHLIGHT_OFF
    01302 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        74,   133,   152,   163, STR_02DA_ON,                     STR_3064_HIGHLIGHT_COVERAGE_AREA},    // BRSW_HIGHLIGHT_ON
    01303 {   WIDGETS_END},
    01304 };
    01305
    01307 static const Widget _newstation_builder_widgets[] = {
    01308 {   WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,    10,     0,    13, STR_00C5,                        STR_018B_CLOSE_WINDOW},               // BRSW_CLOSEBOX
    01309 {    WWT_CAPTION,   RESIZE_NONE,  COLOUR_DARK_GREEN,  11,   147,     0,    13, STR_3000_RAIL_STATION_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS},     // BRSW_CAPTION
    01310 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,   147,    14,   289, 0x0,                             STR_NULL},                            // BRSW_BACKGROUND
    01311 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,         7,    72,   116,   163, 0x0,                             STR_304E_SELECT_RAILROAD_STATION},    // BRSW_PLATFORM_DIR_X
    01312 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,        75,   140,   116,   163, 0x0,                             STR_304E_SELECT_RAILROAD_STATION},    // BRSW_PLATFORM_DIR_Y
    01313
    01314 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        22,    36,   177,   188, STR_00CB_1,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_1
    01315 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        37,    51,   177,   188, STR_00CC_2,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_2
    01316 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        52,    66,   177,   188, STR_00CD_3,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_3
    01317 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        67,    81,   177,   188, STR_00CE_4,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_4
    01318 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        82,    96,   177,   188, STR_00CF_5,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_5
    01319 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        97,   111,   177,   188, STR_6,                           STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_6
    01320 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,       112,   126,   177,   188, STR_7,                           STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_7
    01321
    01322 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        22,    36,   202,   213, STR_00CB_1,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_1
    01323 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        37,    51,   202,   213, STR_00CC_2,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_2
    01324 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        52,    66,   202,   213, STR_00CD_3,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_3
    01325 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        67,    81,   202,   213, STR_00CE_4,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_4
    01326 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        82,    96,   202,   213, STR_00CF_5,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_5
    01327 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        97,   111,   202,   213, STR_6,                           STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_6
    01328 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,       112,   126,   202,   213, STR_7,                           STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_7
    01329
    01330 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        37,   111,   216,   227, STR_DRAG_DROP,                   STR_STATION_DRAG_DROP},               // BRSW_PLATFORM_DRAG_N_DROP
    01331 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        14,    73,   242,   253, STR_02DB_OFF,                    STR_3065_DON_T_HIGHLIGHT_COVERAGE},   // BRSW_HIGHLIGHT_OFF
    01332 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        74,   133,   242,   253, STR_02DA_ON,                     STR_3064_HIGHLIGHT_COVERAGE_AREA},    // BRSW_HIGHLIGHT_ON
    01333
    01334 /* newstations gui additions */
    01335 { WWT_DROPDOWNIN,   RESIZE_NONE,  COLOUR_GREY,         7,   140,    17,    28, STR_02BD,                        STR_SELECT_STATION_CLASS_TIP},        // BRSW_NEWST_DROPDOWN
    01336 {     WWT_MATRIX,   RESIZE_NONE,  COLOUR_GREY,         7,   128,    32,   102, 0x501,                           STR_SELECT_STATION_TYPE_TIP},         // BRSW_NEWST_LIST
    01337 {  WWT_SCROLLBAR,   RESIZE_NONE,  COLOUR_GREY,       129,   140,    32,   102, 0x0,                             STR_0190_SCROLL_BAR_SCROLLS_LIST},    // BRSW_NEWST_SCROLL
    01338 {   WIDGETS_END},
    01339 };
    01340
    01342 static const WindowDesc _station_builder_desc(
    01343   WDP_AUTO, WDP_AUTO, 148, 200, 148, 200,
    01344   WC_BUILD_STATION, WC_BUILD_TOOLBAR,
    01345   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_CONSTRUCTION,
    01346   _station_builder_widgets
    01347 );
    01348
    01350 static const WindowDesc _newstation_builder_desc(
    01351   WDP_AUTO, WDP_AUTO, 148, 290, 148, 290,
    01352   WC_BUILD_STATION, WC_BUILD_TOOLBAR,
    01353   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_CONSTRUCTION,
    01354   _newstation_builder_widgets
    01355 );
    01356
    01358 static void ShowStationBuilder(Window *parent)
    01359 {
    01360   if (GetNumStationClasses() <= 2 && GetNumCustomStations(STAT_CLASS_DFLT) == 1) {
    01361     new BuildRailStationWindow(&_station_builder_desc, parent, false);
    01362   } else {
    01363     new BuildRailStationWindow(&_newstation_builder_desc, parent, true);
    01364   }
    01365 }
    01366
    01368 enum BuildSignalWidgets {
    01369   BSW_CLOSEBOX = 0,
    01370   BSW_CAPTION,
    01371   BSW_SEMAPHORE_NORM,
    01372   BSW_SEMAPHORE_ENTRY,
    01373   BSW_SEMAPHORE_EXIT,
    01374   BSW_SEMAPHORE_COMBO,
    01375   BSW_SEMAPHORE_PBS,
    01376   BSW_SEMAPHORE_PBS_OWAY,
    01377   BSW_ELECTRIC_NORM,
    01378   BSW_ELECTRIC_ENTRY,
    01379   BSW_ELECTRIC_EXIT,
    01380   BSW_ELECTRIC_COMBO,
    01381   BSW_ELECTRIC_PBS,
    01382   BSW_ELECTRIC_PBS_OWAY,
    01383   BSW_CONVERT,
    01384   BSW_DRAG_SIGNALS_DENSITY,
    01385   BSW_DRAG_SIGNALS_DENSITY_DECREASE,
    01386   BSW_DRAG_SIGNALS_DENSITY_INCREASE,
    01387 };
    01388
    01389 struct BuildSignalWindow : public PickerWindowBase {
    01390 private:
    01400   void DrawSignalSprite(byte widget_index, SpriteID image, int8 xrel, uint8 xsize)
    01401   {
    01402     DrawSprite(image + this->IsWidgetLowered(widget_index), PAL_NONE,
    01403         this->widget[widget_index].left + (this->widget[widget_index].right - this->widget[widget_index].left) / 2 - xrel - xsize / 2 +
    01404         this->IsWidgetLowered(widget_index), this->widget[widget_index].bottom - 3 + this->IsWidgetLowered(widget_index));
    01405   }
    01406
    01407 public:
    01408   BuildSignalWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(desc, parent)
    01409   {
    01410     this->FindWindowPlacementAndResize(desc);
    01411   };
    01412
    01413   virtual void OnPaint()
    01414   {
    01415     this->LowerWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type);
    01416
    01417     this->SetWidgetLoweredState(BSW_CONVERT, _convert_signal_button);
    01418
    01419     this->SetWidgetDisabledState(BSW_DRAG_SIGNALS_DENSITY_DECREASE, _settings_client.gui.drag_signals_density == 1);
    01420     this->SetWidgetDisabledState(BSW_DRAG_SIGNALS_DENSITY_INCREASE, _settings_client.gui.drag_signals_density == 20);
    01421
    01422     this->DrawWidgets();
    01423
    01424     /* The 'hardcoded' off sets are needed because they are reused sprites. */
    01425     this->DrawSignalSprite(BSW_SEMAPHORE_NORM,  SPR_IMG_SIGNAL_SEMAPHORE_NORM,   0, 12); // xsize of sprite + 1 ==  9
    01426     this->DrawSignalSprite(BSW_SEMAPHORE_ENTRY, SPR_IMG_SIGNAL_SEMAPHORE_ENTRY, -1, 13); // xsize of sprite + 1 == 10
    01427     this->DrawSignalSprite(BSW_SEMAPHORE_EXIT,  SPR_IMG_SIGNAL_SEMAPHORE_EXIT,   0, 12); // xsize of sprite + 1 ==  9
    01428     this->DrawSignalSprite(BSW_SEMAPHORE_COMBO, SPR_IMG_SIGNAL_SEMAPHORE_COMBO,  0, 12); // xsize of sprite + 1 ==  9
    01429     this->DrawSignalSprite(BSW_SEMAPHORE_PBS,   SPR_IMG_SIGNAL_SEMAPHORE_PBS,    0, 12); // xsize of sprite + 1 ==  9
    01430     this->DrawSignalSprite(BSW_SEMAPHORE_PBS_OWAY, SPR_IMG_SIGNAL_SEMAPHORE_PBS_OWAY, -1, 13); // xsize of sprite + 1 == 10
    01431     this->DrawSignalSprite(BSW_ELECTRIC_NORM,   SPR_IMG_SIGNAL_ELECTRIC_NORM,   -1,  4);
    01432     this->DrawSignalSprite(BSW_ELECTRIC_ENTRY,  SPR_IMG_SIGNAL_ELECTRIC_ENTRY,  -2,  6);
    01433     this->DrawSignalSprite(BSW_ELECTRIC_EXIT,   SPR_IMG_SIGNAL_ELECTRIC_EXIT,   -2,  6);
    01434     this->DrawSignalSprite(BSW_ELECTRIC_COMBO,  SPR_IMG_SIGNAL_ELECTRIC_COMBO,  -2,  6);
    01435     this->DrawSignalSprite(BSW_ELECTRIC_PBS,    SPR_IMG_SIGNAL_ELECTRIC_PBS,    -1,  4);
    01436     this->DrawSignalSprite(BSW_ELECTRIC_PBS_OWAY,SPR_IMG_SIGNAL_ELECTRIC_PBS_OWAY,-2,  6);
    01437
    01438     /* Draw dragging signal density value in the BSW_DRAG_SIGNALS_DENSITY widget */
    01439     SetDParam(0, _settings_client.gui.drag_signals_density);
    01440     DrawStringCentered(this->widget[BSW_DRAG_SIGNALS_DENSITY].left + (this->widget[BSW_DRAG_SIGNALS_DENSITY].right -
    01441         this->widget[BSW_DRAG_SIGNALS_DENSITY].left) / 2 + 1,
    01442         this->widget[BSW_DRAG_SIGNALS_DENSITY].top + 2, STR_JUST_INT, TC_ORANGE);
    01443   }
    01444
    01445   virtual void OnClick(Point pt, int widget)
    01446   {
    01447     switch (widget) {
    01448       case BSW_SEMAPHORE_NORM:
    01449       case BSW_SEMAPHORE_ENTRY:
    01450       case BSW_SEMAPHORE_EXIT:
    01451       case BSW_SEMAPHORE_COMBO:
    01452       case BSW_SEMAPHORE_PBS:
    01453       case BSW_SEMAPHORE_PBS_OWAY:
    01454       case BSW_ELECTRIC_NORM:
    01455       case BSW_ELECTRIC_ENTRY:
    01456       case BSW_ELECTRIC_EXIT:
    01457       case BSW_ELECTRIC_COMBO:
    01458       case BSW_ELECTRIC_PBS:
    01459       case BSW_ELECTRIC_PBS_OWAY:
    01460         this->RaiseWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type);
    01461
    01462         _cur_signal_type = (SignalType)((uint)((widget - BSW_SEMAPHORE_NORM) % (SIGTYPE_LAST + 1)));
    01463         _cur_signal_variant = widget >= BSW_ELECTRIC_NORM ? SIG_ELECTRIC : SIG_SEMAPHORE;
    01464         break;
    01465
    01466       case BSW_CONVERT:
    01467         _convert_signal_button = !_convert_signal_button;
    01468         break;
    01469
    01470       case BSW_DRAG_SIGNALS_DENSITY_DECREASE:
    01471         if (_settings_client.gui.drag_signals_density > 1) {
    01472           _settings_client.gui.drag_signals_density--;
    01473           SetWindowDirty(FindWindowById(WC_GAME_OPTIONS, 0));
    01474         }
    01475         break;
    01476
    01477       case BSW_DRAG_SIGNALS_DENSITY_INCREASE:
    01478         if (_settings_client.gui.drag_signals_density < 20) {
    01479           _settings_client.gui.drag_signals_density++;
    01480           SetWindowDirty(FindWindowById(WC_GAME_OPTIONS, 0));
    01481         }
    01482         break;
    01483
    01484       default: break;
    01485     }
    01486
    01487     this->SetDirty();
    01488   }
    01489 };
    01490
    01492 static const Widget _signal_builder_widgets[] = {
    01493 {   WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,  10,   0,  13, STR_00C5,               STR_018B_CLOSE_WINDOW},                 // BSW_CLOSEBOX
    01494 {    WWT_CAPTION,   RESIZE_NONE,  COLOUR_DARK_GREEN,  11, 153,   0,  13, STR_SIGNAL_SELECTION,   STR_018C_WINDOW_TITLE_DRAG_THIS},       // BSW_CAPTION
    01495
    01496 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,  21,  14,  40, STR_NULL,               STR_BUILD_SIGNAL_SEMAPHORE_NORM_TIP},   // BSW_SEMAPHORE_NORM
    01497 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  22,  43,  14,  40, STR_NULL,               STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TIP},  // BSW_SEMAPHORE_ENTRY
    01498 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  44,  65,  14,  40, STR_NULL,               STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TIP},   // BSW_SEMAPHORE_EXIT
    01499 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  66,  87,  14,  40, STR_NULL,               STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TIP},  // BSW_SEMAPHORE_COMBO
    01500 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  88, 109,  14,  40, STR_NULL,               STR_BUILD_SIGNAL_SEMAPHORE_PBS_TIP},    // BSW_SEMAPHORE_PBS
    01501 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN, 110, 131,  14,  40, STR_NULL,               STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TIP},// BSW_SEMAPHORE_PBS_OWAY
    01502
    01503 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,  21,  41,  67, STR_NULL,               STR_BUILD_SIGNAL_ELECTRIC_NORM_TIP},    // BSW_ELECTRIC_NORM
    01504 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  22,  43,  41,  67, STR_NULL,               STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TIP},   // BSW_ELECTRIC_ENTRY
    01505 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  44,  65,  41,  67, STR_NULL,               STR_BUILD_SIGNAL_ELECTRIC_EXIT_TIP},    // BSW_ELECTRIC_EXIT
    01506 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  66,  87,  41,  67, STR_NULL,               STR_BUILD_SIGNAL_ELECTRIC_COMBO_TIP},   // BSW_ELECTRIC_COMBO
    01507 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  88, 109,  41,  67, STR_NULL,               STR_BUILD_SIGNAL_ELECTRIC_PBS_TIP},     // BSW_ELECTRIC_PBS
    01508 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN, 110, 131,  41,  67, STR_NULL,               STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TIP},// BSW_ELECTRIC_PBS_OWAY
    01509
    01510 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN, 132, 153,  14,  40, SPR_IMG_SIGNAL_CONVERT, STR_SIGNAL_CONVERT_TIP},                // BSW_CONVERT
    01511 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN, 132, 153,  41,  67, STR_NULL,               STR_DRAG_SIGNALS_DENSITY_TIP},          // BSW_DRAG_SIGNALS_DENSITY
    01512 { WWT_PUSHIMGBTN,   RESIZE_NONE,  COLOUR_GREY,       134, 142,  54,  65, SPR_ARROW_LEFT,         STR_DRAG_SIGNALS_DENSITY_DECREASE_TIP}, // BSW_DRAG_SIGNALS_DENSITY_DECREASE
    01513 { WWT_PUSHIMGBTN,   RESIZE_NONE,  COLOUR_GREY,       143, 151,  54,  65, SPR_ARROW_RIGHT,        STR_DRAG_SIGNALS_DENSITY_INCREASE_TIP}, // BSW_DRAG_SIGNALS_DENSITY_INCREASE
    01514
    01515 {   WIDGETS_END},
    01516 };
    01517
    01519 static const WindowDesc _signal_builder_desc(
    01520   WDP_AUTO, WDP_AUTO, 154, 68, 154, 68,
    01521   WC_BUILD_SIGNAL, WC_BUILD_TOOLBAR,
    01522   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_CONSTRUCTION,
    01523   _signal_builder_widgets
    01524 );
    01525
    01529 static void ShowSignalBuilder(Window *parent)
    01530 {
    01531   new BuildSignalWindow(&_signal_builder_desc, parent);
    01532 }
    01533
    01534 struct BuildRailDepotWindow : public PickerWindowBase {
    01535 private:
    01537   enum BuildRailDepotWidgets {
    01538     BRDW_CLOSEBOX = 0,
    01539     BRDW_CAPTION,
    01540     BRDW_BACKGROUND,
    01541     BRDW_DEPOT_NE,
    01542     BRDW_DEPOT_SE,
    01543     BRDW_DEPOT_SW,
    01544     BRDW_DEPOT_NW,
    01545   };
    01546
    01547 public:
    01548   BuildRailDepotWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(desc, parent)
    01549   {
    01550     this->LowerWidget(_build_depot_direction + BRDW_DEPOT_NE);
    01551     this->FindWindowPlacementAndResize(desc);
    01552   }
    01553
    01554   virtual void OnPaint()
    01555   {
    01556     this->DrawWidgets();
    01557
    01558     DrawTrainDepotSprite(70, 17, DIAGDIR_NE, _cur_railtype);
    01559     DrawTrainDepotSprite(70, 69, DIAGDIR_SE, _cur_railtype);
    01560     DrawTrainDepotSprite( 2, 69, DIAGDIR_SW, _cur_railtype);
    01561     DrawTrainDepotSprite( 2, 17, DIAGDIR_NW, _cur_railtype);
    01562   }
    01563
    01564   virtual void OnClick(Point pt, int widget)
    01565   {
    01566     switch (widget) {
    01567       case BRDW_DEPOT_NE:
    01568       case BRDW_DEPOT_SE:
    01569       case BRDW_DEPOT_SW:
    01570       case BRDW_DEPOT_NW:
    01571         this->RaiseWidget(_build_depot_direction + BRDW_DEPOT_NE);
    01572         _build_depot_direction = (DiagDirection)(widget - BRDW_DEPOT_NE);
    01573         this->LowerWidget(_build_depot_direction + BRDW_DEPOT_NE);
    01574         SndPlayFx(SND_15_BEEP);
    01575         this->SetDirty();
    01576         break;
    01577     }
    01578   }
    01579 };
    01580
    01582 static const Widget _build_depot_widgets[] = {
    01583 {   WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,    10,     0,    13, STR_00C5,                         STR_018B_CLOSE_WINDOW},                     // BRDW_CLOSEBOX
    01584 {    WWT_CAPTION,   RESIZE_NONE,  COLOUR_DARK_GREEN,  11,   139,     0,    13, STR_1014_TRAIN_DEPOT_ORIENTATION, STR_018C_WINDOW_TITLE_DRAG_THIS},           // BRDW_CAPTION
    01585 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,   139,    14,   121, 0x0,                              STR_NULL},                                  // BRDW_BACKGROUND
    01586 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,        71,   136,    17,    66, 0x0,                              STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO}, // BRDW_DEPOT_NE
    01587 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,        71,   136,    69,   118, 0x0,                              STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO}, // BRDW_DEPOT_SE
    01588 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,         3,    68,    69,   118, 0x0,                              STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO}, // BRDW_DEPOT_SW
    01589 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,         3,    68,    17,    66, 0x0,                              STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO}, // BRDW_DEPOT_NW
    01590 {   WIDGETS_END},
    01591 };
    01592
    01593 static const WindowDesc _build_depot_desc(
    01594   WDP_AUTO, WDP_AUTO, 140, 122, 140, 122,
    01595   WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
    01596   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_CONSTRUCTION,
    01597   _build_depot_widgets
    01598 );
    01599
    01600 static void ShowBuildTrainDepotPicker(Window *parent)
    01601 {
    01602   new BuildRailDepotWindow(&_build_depot_desc, parent);
    01603 }
    01604
    01605 struct BuildRailWaypointWindow : PickerWindowBase {
    01606 private:
    01608   enum BuildRailWaypointWidgets {
    01609     BRWW_CLOSEBOX = 0,
    01610     BRWW_CAPTION,
    01611     BRWW_BACKGROUND,
    01612     BRWW_WAYPOINT_1,
    01613     BRWW_WAYPOINT_2,
    01614     BRWW_WAYPOINT_3,
    01615     BRWW_WAYPOINT_4,
    01616     BRWW_WAYPOINT_5,
    01617     BRWW_SCROLL,
    01618   };
    01619
    01620 public:
    01621   BuildRailWaypointWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(desc, parent)
    01622   {
    01623     this->hscroll.cap = 5;
    01624     this->hscroll.count = _waypoint_count;
    01625     this->FindWindowPlacementAndResize(desc);
    01626   };
    01627
    01628   virtual void OnPaint()
    01629   {
    01630     uint i;
    01631
    01632     for (i = 0; i < this->hscroll.cap; i++) {
    01633       this->SetWidgetLoweredState(i + BRWW_WAYPOINT_1, (this->hscroll.pos + i) == _cur_waypoint_type);
    01634     }
    01635
    01636     this->DrawWidgets();
    01637
    01638     for (i = 0; i < this->hscroll.cap; i++) {
    01639       if (this->hscroll.pos + i < this->hscroll.count) {
    01640         const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, this->hscroll.pos + i);
    01641
    01642         DrawWaypointSprite(2 + i * 68, 25, this->hscroll.pos + i, _cur_railtype);
    01643
    01644         if (statspec != NULL &&
    01645             HasBit(statspec->callbackmask, CBM_STATION_AVAIL) &&
    01646             GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) {
    01647           GfxFillRect(4 + i * 68, 18, 67 + i * 68, 75, 0, FILLRECT_CHECKER);
    01648         }
    01649       }
    01650     }
    01651   }
    01652
    01653   virtual void OnClick(Point pt, int widget)
    01654   {
    01655     switch (widget) {
    01656       case BRWW_WAYPOINT_1:
    01657       case BRWW_WAYPOINT_2:
    01658       case BRWW_WAYPOINT_3:
    01659       case BRWW_WAYPOINT_4:
    01660       case BRWW_WAYPOINT_5: {
    01661         byte type = widget - BRWW_WAYPOINT_1 + this->hscroll.pos;
    01662
    01663         /* Check station availability callback */
    01664         const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, type);
    01665         if (statspec != NULL &&
    01666             HasBit(statspec->callbackmask, CBM_STATION_AVAIL) &&
    01667             GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) return;
    01668
    01669         _cur_waypoint_type = type;
    01670         SndPlayFx(SND_15_BEEP);
    01671         this->SetDirty();
    01672         break;
    01673       }
    01674     }
    01675   }
    01676 };
    01677
    01679 static const Widget _build_waypoint_widgets[] = {
    01680 {   WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN,     0,    10,     0,    13, STR_00C5,     STR_018B_CLOSE_WINDOW},            // BRWW_CLOSEBOX
    01681 {    WWT_CAPTION,   RESIZE_NONE,  COLOUR_DARK_GREEN,    11,   343,     0,    13, STR_WAYPOINT, STR_018C_WINDOW_TITLE_DRAG_THIS},  // BRWW_CAPTION
    01682 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,     0,   343,    14,    91, 0x0,          STR_NULL},                         // BRWW_BACKGROUND
    01683
    01684 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,     3,    68,    17,    76, 0x0,          STR_WAYPOINT_GRAPHICS_TIP},        // BRWW_WAYPOINT_1
    01685 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,    71,   136,    17,    76, 0x0,          STR_WAYPOINT_GRAPHICS_TIP},        // BRWW_WAYPOINT_2
    01686 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   139,   204,    17,    76, 0x0,          STR_WAYPOINT_GRAPHICS_TIP},        // BRWW_WAYPOINT_3
    01687 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   207,   272,    17,    76, 0x0,          STR_WAYPOINT_GRAPHICS_TIP},        // BRWW_WAYPOINT_4
    01688 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   275,   340,    17,    76, 0x0,          STR_WAYPOINT_GRAPHICS_TIP},        // BRWW_WAYPOINT_5
    01689
    01690 { WWT_HSCROLLBAR,   RESIZE_NONE,  COLOUR_DARK_GREEN,     1,   343,     80,    91, 0x0,          STR_HSCROLL_BAR_SCROLLS_LIST},     // BRWW_SCROLL
    01691 {    WIDGETS_END},
    01692 };
    01693
    01694 static const WindowDesc _build_waypoint_desc(
    01695   WDP_AUTO, WDP_AUTO, 344, 92, 344, 92,
    01696   WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
    01697   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_CONSTRUCTION,
    01698   _build_waypoint_widgets
    01699 );
    01700
    01701 static void ShowBuildWaypointPicker(Window *parent)
    01702 {
    01703   new BuildRailWaypointWindow(&_build_waypoint_desc, parent);
    01704 }
    01705
    01709 void InitializeRailGui()
    01710 {
    01711   _build_depot_direction = DIAGDIR_NW;
    01712 }
    01713
    01718 void ReinitGuiAfterToggleElrail(bool disable)
    01719 {
    01720   extern RailType _last_built_railtype;
    01721   if (disable && _last_built_railtype == RAILTYPE_ELECTRIC) {
    01722     Window *w;
    01723     _last_built_railtype = _cur_railtype = RAILTYPE_RAIL;
    01724     w = FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_RAIL);
    01725     if (w != NULL) {
    01726       SetupRailToolbar(_cur_railtype, w);
    01727       w->SetDirty();
    01728     }
    01729   }
    01730   MarkWholeScreenDirty();
    01731 }
    01732
    01734 static void SetDefaultRailGui()
    01735 {
    01736   if (_local_company == COMPANY_SPECTATOR || !IsValidCompanyID(_local_company)) return;
    01737
    01738   extern RailType _last_built_railtype;
    01739   RailType rt = (RailType)_settings_client.gui.default_rail_type;
    01740   if (rt >= RAILTYPE_END) {
    01741     if (rt == RAILTYPE_END + 2) {
    01742       /* Find the most used rail type */
    01743       RailType count[RAILTYPE_END];
    01744       memset(count, 0, sizeof(count));
    01745       for (TileIndex t = 0; t < MapSize(); t++) {
    01746         if (IsTileType(t, MP_RAILWAY) || IsLevelCrossingTile(t) || IsRailwayStationTile(t) ||
    01747             (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL)) {
    01748           count[GetRailType(t)]++;
    01749         }
    01750       }
    01751
    01752       rt = RAILTYPE_RAIL;
    01753       for (RailType r = RAILTYPE_ELECTRIC; r < RAILTYPE_END; r++) {
    01754         if (count[r] >= count[rt]) rt = r;
    01755       }
    01756
    01757       /* No rail, just get the first available one */
    01758       if (count[rt] == 0) rt = RAILTYPE_END;
    01759     }
    01760     switch (rt) {
    01761       case RAILTYPE_END + 0:
    01762         rt = RAILTYPE_RAIL;
    01763         while (rt < RAILTYPE_END && !HasRailtypeAvail(_local_company, rt)) rt++;
    01764         break;
    01765
    01766       case RAILTYPE_END + 1:
    01767         rt = GetBestRailtype(_local_company);
    01768         break;
    01769
    01770       default:
    01771         break;
    01772     }
    01773   }
    01774
    01775   _last_built_railtype = _cur_railtype = rt;
    01776   Window *w = FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_RAIL);
    01777   if (w != NULL) {
    01778     SetupRailToolbar(_cur_railtype, w);
    01779     w->SetDirty();
    01780   }
    01781 }
    01782
    01789 bool ResetSignalVariant(int32 = 0)
    01790 {
    01791   SignalVariant new_variant = (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC);
    01792
    01793   if (new_variant != _cur_signal_variant) {
    01794     Window *w = FindWindowById(WC_BUILD_SIGNAL, 0);
    01795     if (w != NULL) {
    01796       w->SetDirty();
    01797       w->RaiseWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type);
    01798     }
    01799     _cur_signal_variant = new_variant;
    01800   }
    01801
    01802   return true;
    01803 }
    01804
    01808 void InitializeRailGUI()
    01809 {
    01810   SetDefaultRailGui();
    01811
    01812   _convert_signal_button = false;
    01813   _cur_signal_type = _default_signal_type[_settings_client.gui.default_signal_type];
    01814   ResetSignalVariant();
    01815 }