# rail_gui.cpp

Go to the documentation of this file.

    00001 /* $Id: rail_gui.cpp 15415 2009-02-08 16:03:17Z 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     }
    00993   }
    00994
    00995   virtual ~BuildRailStationWindow()
    00996   {
    00997     DeleteWindowById(WC_SELECT_STATION, 0);
    00998   }
    00999
    01000   virtual void OnPaint()
    01001   {
    01002     bool newstations = _railstation.newstations;
    01003     DrawPixelInfo tmp_dpi, *old_dpi;
    01004     const StationSpec *statspec = newstations ? GetCustomStationSpec(_railstation.station_class, _railstation.station_type) : NULL;
    01005
    01006     if (_settings_client.gui.station_dragdrop) {
    01007       SetTileSelectSize(1, 1);
    01008     } else {
    01009       int x = _settings_client.gui.station_numtracks;
    01010       int y = _settings_client.gui.station_platlength;
    01011       if (_railstation.orientation == AXIS_X) Swap(x, y);
    01012       if (!_remove_button_clicked)
    01013         SetTileSelectSize(x, y);
    01014     }
    01015
    01016     int rad = (_settings_game.station.modified_catchment) ? CA_TRAIN : CA_UNMODIFIED;
    01017
    01018     if (_settings_client.gui.station_show_coverage)
    01019       SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
    01020
    01021     for (uint bits = 0; bits < 7; bits++) {
    01022       bool disable = bits >= _settings_game.station.station_spread;
    01023       if (statspec == NULL) {
    01024         this->SetWidgetDisabledState(bits + BRSW_PLATFORM_NUM_1, disable);
    01025         this->SetWidgetDisabledState(bits + BRSW_PLATFORM_LEN_1, disable);
    01026       } else {
    01027         this->SetWidgetDisabledState(bits + BRSW_PLATFORM_NUM_1, HasBit(statspec->disallowed_platforms, bits) || disable);
    01028         this->SetWidgetDisabledState(bits + BRSW_PLATFORM_LEN_1, HasBit(statspec->disallowed_lengths,   bits) || disable);
    01029       }
    01030     }
    01031
    01032     SetDParam(0, GetStationClassName(_railstation.station_class));
    01033     this->DrawWidgets();
    01034
    01035     int y_offset = newstations ? 90 : 0;
    01036
    01037     /* Set up a clipping area for the '/' station preview */
    01038     if (FillDrawPixelInfo(&tmp_dpi, 7, 26 + y_offset, 66, 48)) {
    01039       old_dpi = _cur_dpi;
    01040       _cur_dpi = &tmp_dpi;
    01041       if (!DrawStationTile(32, 16, _cur_railtype, AXIS_X, _railstation.station_class, _railstation.station_type)) {
    01042         StationPickerDrawSprite(32, 16, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2);
    01043       }
    01044       _cur_dpi = old_dpi;
    01045     }
    01046
    01047     /* Set up a clipping area for the '\' station preview */
    01048     if (FillDrawPixelInfo(&tmp_dpi, 75, 26 + y_offset, 66, 48)) {
    01049       old_dpi = _cur_dpi;
    01050       _cur_dpi = &tmp_dpi;
    01051       if (!DrawStationTile(32, 16, _cur_railtype, AXIS_Y, _railstation.station_class, _railstation.station_type)) {
    01052         StationPickerDrawSprite(32, 16, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 3);
    01053       }
    01054       _cur_dpi = old_dpi;
    01055     }
    01056
    01057     DrawStringCentered(74, 15 + y_offset, STR_3002_ORIENTATION, TC_FROMSTRING);
    01058     DrawStringCentered(74, 76 + y_offset, STR_3003_NUMBER_OF_TRACKS, TC_FROMSTRING);
    01059     DrawStringCentered(74, 101 + y_offset, STR_3004_PLATFORM_LENGTH, TC_FROMSTRING);
    01060     DrawStringCentered(74, 141 + y_offset, STR_3066_COVERAGE_AREA_HIGHLIGHT, TC_FROMSTRING);
    01061
    01062     int text_end = DrawStationCoverageAreaText(2, 166 + y_offset, SCT_ALL, rad, false);
    01063     text_end = DrawStationCoverageAreaText(2, text_end + 4, SCT_ALL, rad, true) + 4;
    01064     if (text_end != this->widget[BRSW_BACKGROUND].bottom) {
    01065       this->SetDirty();
    01066       ResizeWindowForWidget(this, BRSW_BACKGROUND, 0, text_end - this->widget[BRSW_BACKGROUND].bottom);
    01067       this->SetDirty();
    01068     }
    01069
    01070     if (newstations) {
    01071       uint y = 35;
    01072
    01073       for (uint16 i = this->vscroll.pos; i < _railstation.station_count && i < (uint)(this->vscroll.pos + this->vscroll.cap); i++) {
    01074         const StationSpec *statspec = GetCustomStationSpec(_railstation.station_class, i);
    01075
    01076         if (statspec != NULL && statspec->name != 0) {
    01077           if (HasBit(statspec->callbackmask, CBM_STATION_AVAIL) && GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) {
    01078             GfxFillRect(8, y - 2, 127, y + 10, 0, FILLRECT_CHECKER);
    01079           }
    01080
    01081           DrawStringTruncated(9, y, statspec->name, i == _railstation.station_type ? TC_WHITE : TC_BLACK, 118);
    01082         } else {
    01083           DrawStringTruncated(9, y, STR_STAT_CLASS_DFLT, i == _railstation.station_type ? TC_WHITE : TC_BLACK, 118);
    01084         }
    01085
    01086         y += 14;
    01087       }
    01088     }
    01089   }
    01090
    01091   virtual void OnClick(Point pt, int widget)
    01092   {
    01093     switch (widget) {
    01094       case BRSW_PLATFORM_DIR_X:
    01095       case BRSW_PLATFORM_DIR_Y:
    01096         this->RaiseWidget(_railstation.orientation + BRSW_PLATFORM_DIR_X);
    01097         _railstation.orientation = (Axis)(widget - BRSW_PLATFORM_DIR_X);
    01098         this->LowerWidget(_railstation.orientation + BRSW_PLATFORM_DIR_X);
    01099         SndPlayFx(SND_15_BEEP);
    01100         this->SetDirty();
    01101         DeleteWindowById(WC_SELECT_STATION, 0);
    01102         break;
    01103
    01104       case BRSW_PLATFORM_NUM_1:
    01105       case BRSW_PLATFORM_NUM_2:
    01106       case BRSW_PLATFORM_NUM_3:
    01107       case BRSW_PLATFORM_NUM_4:
    01108       case BRSW_PLATFORM_NUM_5:
    01109       case BRSW_PLATFORM_NUM_6:
    01110       case BRSW_PLATFORM_NUM_7: {
    01111         this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
    01112         this->RaiseWidget(BRSW_PLATFORM_DRAG_N_DROP);
    01113
    01114         _settings_client.gui.station_numtracks = widget - BRSW_PLATFORM_NUM_BEGIN;
    01115         _settings_client.gui.station_dragdrop = false;
    01116
    01117         _settings_client.gui.station_dragdrop = false;
    01118
    01119         const StationSpec *statspec = _railstation.newstations ? GetCustomStationSpec(_railstation.station_class, _railstation.station_type) : NULL;
    01120         if (statspec != NULL && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
    01121           /* The previously selected number of platforms in invalid */
    01122           for (uint i = 0; i < 7; i++) {
    01123             if (!HasBit(statspec->disallowed_lengths, i)) {
    01124               this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
    01125               _settings_client.gui.station_platlength = i + 1;
    01126               break;
    01127             }
    01128           }
    01129         }
    01130
    01131         this->LowerWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
    01132         this->LowerWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
    01133         SndPlayFx(SND_15_BEEP);
    01134         this->SetDirty();
    01135         DeleteWindowById(WC_SELECT_STATION, 0);
    01136         break;
    01137       }
    01138
    01139       case BRSW_PLATFORM_LEN_1:
    01140       case BRSW_PLATFORM_LEN_2:
    01141       case BRSW_PLATFORM_LEN_3:
    01142       case BRSW_PLATFORM_LEN_4:
    01143       case BRSW_PLATFORM_LEN_5:
    01144       case BRSW_PLATFORM_LEN_6:
    01145       case BRSW_PLATFORM_LEN_7: {
    01146         this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
    01147         this->RaiseWidget(BRSW_PLATFORM_DRAG_N_DROP);
    01148
    01149         _settings_client.gui.station_platlength = widget - BRSW_PLATFORM_LEN_BEGIN;
    01150         _settings_client.gui.station_dragdrop = false;
    01151
    01152         _settings_client.gui.station_dragdrop = false;
    01153
    01154         const StationSpec *statspec = _railstation.newstations ? GetCustomStationSpec(_railstation.station_class, _railstation.station_type) : NULL;
    01155         if (statspec != NULL && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
    01156           /* The previously selected number of tracks in invalid */
    01157           for (uint i = 0; i < 7; i++) {
    01158             if (!HasBit(statspec->disallowed_platforms, i)) {
    01159               this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
    01160               _settings_client.gui.station_numtracks = i + 1;
    01161               break;
    01162             }
    01163           }
    01164         }
    01165
    01166         this->LowerWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
    01167         this->LowerWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
    01168         SndPlayFx(SND_15_BEEP);
    01169         this->SetDirty();
    01170         DeleteWindowById(WC_SELECT_STATION, 0);
    01171         break;
    01172       }
    01173
    01174       case BRSW_PLATFORM_DRAG_N_DROP: {
    01175         _settings_client.gui.station_dragdrop ^= true;
    01176
    01177         this->ToggleWidgetLoweredState(BRSW_PLATFORM_DRAG_N_DROP);
    01178
    01179         /* get the first allowed length/number of platforms */
    01180         const StationSpec *statspec = _railstation.newstations ? GetCustomStationSpec(_railstation.station_class, _railstation.station_type) : NULL;
    01181         if (statspec != NULL && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
    01182           for (uint i = 0; i < 7; i++) {
    01183             if (!HasBit(statspec->disallowed_lengths, i)) {
    01184               this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
    01185               _settings_client.gui.station_platlength = i + 1;
    01186               break;
    01187             }
    01188           }
    01189         }
    01190         if (statspec != NULL && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
    01191           for (uint i = 0; i < 7; i++) {
    01192             if (!HasBit(statspec->disallowed_platforms, i)) {
    01193               this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
    01194               _settings_client.gui.station_numtracks = i + 1;
    01195               break;
    01196             }
    01197           }
    01198         }
    01199
    01200         this->SetWidgetLoweredState(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN, !_settings_client.gui.station_dragdrop);
    01201         this->SetWidgetLoweredState(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN, !_settings_client.gui.station_dragdrop);
    01202         SndPlayFx(SND_15_BEEP);
    01203         this->SetDirty();
    01204         DeleteWindowById(WC_SELECT_STATION, 0);
    01205       } break;
    01206
    01207       case BRSW_HIGHLIGHT_OFF:
    01208       case BRSW_HIGHLIGHT_ON:
    01209         _settings_client.gui.station_show_coverage = (widget != BRSW_HIGHLIGHT_OFF);
    01210
    01211         this->SetWidgetLoweredState(BRSW_HIGHLIGHT_OFF, !_settings_client.gui.station_show_coverage);
    01212         this->SetWidgetLoweredState(BRSW_HIGHLIGHT_ON, _settings_client.gui.station_show_coverage);
    01213         SndPlayFx(SND_15_BEEP);
    01214         this->SetDirty();
    01215         break;
    01216
    01217       case BRSW_NEWST_DROPDOWN:
    01218         ShowDropDownList(this, BuildStationClassDropDown(), _railstation.station_class, BRSW_NEWST_DROPDOWN);
    01219         break;
    01220
    01221       case BRSW_NEWST_LIST: {
    01222         const StationSpec *statspec;
    01223         int y = (pt.y - 32) / 14;
    01224
    01225         if (y >= this->vscroll.cap) return;
    01226         y += this->vscroll.pos;
    01227         if (y >= _railstation.station_count) return;
    01228
    01229         /* Check station availability callback */
    01230         statspec = GetCustomStationSpec(_railstation.station_class, y);
    01231         if (statspec != NULL &&
    01232           HasBit(statspec->callbackmask, CBM_STATION_AVAIL) &&
    01233           GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) return;
    01234
    01235         _railstation.station_type = y;
    01236
    01237         this->CheckSelectedSize(statspec);
    01238
    01239         SndPlayFx(SND_15_BEEP);
    01240         this->SetDirty();
    01241         DeleteWindowById(WC_SELECT_STATION, 0);
    01242         break;
    01243       }
    01244     }
    01245   }
    01246
    01247   virtual void OnDropdownSelect(int widget, int index)
    01248   {
    01249     if (_railstation.station_class != index) {
    01250       _railstation.station_class = (StationClassID)index;
    01251       _railstation.station_type  = 0;
    01252       _railstation.station_count = GetNumCustomStations(_railstation.station_class);
    01253
    01254       this->CheckSelectedSize(GetCustomStationSpec(_railstation.station_class, _railstation.station_type));
    01255
    01256       this->vscroll.count = _railstation.station_count;
    01257       this->vscroll.pos   = _railstation.station_type;
    01258     }
    01259
    01260     SndPlayFx(SND_15_BEEP);
    01261     this->SetDirty();
    01262     DeleteWindowById(WC_SELECT_STATION, 0);
    01263   }
    01264
    01265   virtual void OnTick()
    01266   {
    01267     CheckRedrawStationCoverage(this);
    01268   }
    01269 };
    01270
    01272 static const Widget _station_builder_widgets[] = {
    01273 {   WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,    10,     0,    13, STR_00C5,                        STR_018B_CLOSE_WINDOW},               // BRSW_CLOSEBOX
    01274 {    WWT_CAPTION,   RESIZE_NONE,  COLOUR_DARK_GREEN,  11,   147,     0,    13, STR_3000_RAIL_STATION_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS},     // BRSW_CAPTION
    01275 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,   147,    14,   199, 0x0,                             STR_NULL},                            // BRSW_BACKGROUND
    01276 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,         7,    72,    26,    73, 0x0,                             STR_304E_SELECT_RAILROAD_STATION},    // BRSW_PLATFORM_DIR_X
    01277 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,        75,   140,    26,    73, 0x0,                             STR_304E_SELECT_RAILROAD_STATION},    // BRSW_PLATFORM_DIR_Y
    01278
    01279 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        22,    36,    87,    98, STR_00CB_1,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_1
    01280 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        37,    51,    87,    98, STR_00CC_2,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_2
    01281 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        52,    66,    87,    98, STR_00CD_3,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_3
    01282 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        67,    81,    87,    98, STR_00CE_4,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_4
    01283 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        82,    96,    87,    98, STR_00CF_5,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_5
    01284 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        97,   111,    87,    98, STR_6,                           STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_6
    01285 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,       112,   126,    87,    98, STR_7,                           STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_7
    01286
    01287 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        22,    36,   112,   123, STR_00CB_1,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_1
    01288 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        37,    51,   112,   123, STR_00CC_2,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_2
    01289 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        52,    66,   112,   123, STR_00CD_3,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_3
    01290 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        67,    81,   112,   123, STR_00CE_4,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_4
    01291 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        82,    96,   112,   123, STR_00CF_5,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_5
    01292 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        97,   111,   112,   123, STR_6,                           STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_6
    01293 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,       112,   126,   112,   123, STR_7,                           STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_7
    01294
    01295 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        37,   111,   126,   137, STR_DRAG_DROP,                   STR_STATION_DRAG_DROP},               // BRSW_PLATFORM_DRAG_N_DROP
    01296 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        14,    73,   152,   163, STR_02DB_OFF,                    STR_3065_DON_T_HIGHLIGHT_COVERAGE},   // BRSW_HIGHLIGHT_OFF
    01297 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        74,   133,   152,   163, STR_02DA_ON,                     STR_3064_HIGHLIGHT_COVERAGE_AREA},    // BRSW_HIGHLIGHT_ON
    01298 {   WIDGETS_END},
    01299 };
    01300
    01302 static const Widget _newstation_builder_widgets[] = {
    01303 {   WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,    10,     0,    13, STR_00C5,                        STR_018B_CLOSE_WINDOW},               // BRSW_CLOSEBOX
    01304 {    WWT_CAPTION,   RESIZE_NONE,  COLOUR_DARK_GREEN,  11,   147,     0,    13, STR_3000_RAIL_STATION_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS},     // BRSW_CAPTION
    01305 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,   147,    14,   289, 0x0,                             STR_NULL},                            // BRSW_BACKGROUND
    01306 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,         7,    72,   116,   163, 0x0,                             STR_304E_SELECT_RAILROAD_STATION},    // BRSW_PLATFORM_DIR_X
    01307 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,        75,   140,   116,   163, 0x0,                             STR_304E_SELECT_RAILROAD_STATION},    // BRSW_PLATFORM_DIR_Y
    01308
    01309 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        22,    36,   177,   188, STR_00CB_1,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_1
    01310 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        37,    51,   177,   188, STR_00CC_2,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_2
    01311 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        52,    66,   177,   188, STR_00CD_3,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_3
    01312 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        67,    81,   177,   188, STR_00CE_4,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_4
    01313 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        82,    96,   177,   188, STR_00CF_5,                      STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_5
    01314 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        97,   111,   177,   188, STR_6,                           STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_6
    01315 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,       112,   126,   177,   188, STR_7,                           STR_304F_SELECT_NUMBER_OF_PLATFORMS}, // BRSW_PLATFORM_NUM_7
    01316
    01317 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        22,    36,   202,   213, STR_00CB_1,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_1
    01318 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        37,    51,   202,   213, STR_00CC_2,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_2
    01319 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        52,    66,   202,   213, STR_00CD_3,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_3
    01320 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        67,    81,   202,   213, STR_00CE_4,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_4
    01321 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        82,    96,   202,   213, STR_00CF_5,                      STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_5
    01322 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        97,   111,   202,   213, STR_6,                           STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_6
    01323 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,       112,   126,   202,   213, STR_7,                           STR_3050_SELECT_LENGTH_OF_RAILROAD},  // BRSW_PLATFORM_LEN_7
    01324
    01325 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        37,   111,   216,   227, STR_DRAG_DROP,                   STR_STATION_DRAG_DROP},               // BRSW_PLATFORM_DRAG_N_DROP
    01326 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        14,    73,   242,   253, STR_02DB_OFF,                    STR_3065_DON_T_HIGHLIGHT_COVERAGE},   // BRSW_HIGHLIGHT_OFF
    01327 {    WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,        74,   133,   242,   253, STR_02DA_ON,                     STR_3064_HIGHLIGHT_COVERAGE_AREA},    // BRSW_HIGHLIGHT_ON
    01328
    01329 /* newstations gui additions */
    01330 { WWT_DROPDOWNIN,   RESIZE_NONE,  COLOUR_GREY,         7,   140,    17,    28, STR_02BD,                        STR_SELECT_STATION_CLASS_TIP},        // BRSW_NEWST_DROPDOWN
    01331 {     WWT_MATRIX,   RESIZE_NONE,  COLOUR_GREY,         7,   128,    32,   102, 0x501,                           STR_SELECT_STATION_TYPE_TIP},         // BRSW_NEWST_LIST
    01332 {  WWT_SCROLLBAR,   RESIZE_NONE,  COLOUR_GREY,       129,   140,    32,   102, 0x0,                             STR_0190_SCROLL_BAR_SCROLLS_LIST},    // BRSW_NEWST_SCROLL
    01333 {   WIDGETS_END},
    01334 };
    01335
    01337 static const WindowDesc _station_builder_desc = {
    01338   WDP_AUTO, WDP_AUTO, 148, 200, 148, 200,
    01339   WC_BUILD_STATION, WC_BUILD_TOOLBAR,
    01340   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_CONSTRUCTION,
    01341   _station_builder_widgets,
    01342 };
    01343
    01345 static const WindowDesc _newstation_builder_desc = {
    01346   WDP_AUTO, WDP_AUTO, 148, 290, 148, 290,
    01347   WC_BUILD_STATION, WC_BUILD_TOOLBAR,
    01348   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_CONSTRUCTION,
    01349   _newstation_builder_widgets,
    01350 };
    01351
    01353 static void ShowStationBuilder(Window *parent)
    01354 {
    01355   if (GetNumStationClasses() <= 2 && GetNumCustomStations(STAT_CLASS_DFLT) == 1) {
    01356     new BuildRailStationWindow(&_station_builder_desc, parent, false);
    01357   } else {
    01358     new BuildRailStationWindow(&_newstation_builder_desc, parent, true);
    01359   }
    01360 }
    01361
    01363 enum BuildSignalWidgets {
    01364   BSW_CLOSEBOX = 0,
    01365   BSW_CAPTION,
    01366   BSW_SEMAPHORE_NORM,
    01367   BSW_SEMAPHORE_ENTRY,
    01368   BSW_SEMAPHORE_EXIT,
    01369   BSW_SEMAPHORE_COMBO,
    01370   BSW_SEMAPHORE_PBS,
    01371   BSW_SEMAPHORE_PBS_OWAY,
    01372   BSW_ELECTRIC_NORM,
    01373   BSW_ELECTRIC_ENTRY,
    01374   BSW_ELECTRIC_EXIT,
    01375   BSW_ELECTRIC_COMBO,
    01376   BSW_ELECTRIC_PBS,
    01377   BSW_ELECTRIC_PBS_OWAY,
    01378   BSW_CONVERT,
    01379   BSW_DRAG_SIGNALS_DENSITY,
    01380   BSW_DRAG_SIGNALS_DENSITY_DECREASE,
    01381   BSW_DRAG_SIGNALS_DENSITY_INCREASE,
    01382 };
    01383
    01384 struct BuildSignalWindow : public PickerWindowBase {
    01385 private:
    01395   void DrawSignalSprite(byte widget_index, SpriteID image, int8 xrel, uint8 xsize)
    01396   {
    01397     DrawSprite(image + this->IsWidgetLowered(widget_index), PAL_NONE,
    01398         this->widget[widget_index].left + (this->widget[widget_index].right - this->widget[widget_index].left) / 2 - xrel - xsize / 2 +
    01399         this->IsWidgetLowered(widget_index), this->widget[widget_index].bottom - 3 + this->IsWidgetLowered(widget_index));
    01400   }
    01401
    01402 public:
    01403   BuildSignalWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(desc, parent)
    01404   {
    01405     this->FindWindowPlacementAndResize(desc);
    01406   };
    01407
    01408   virtual void OnPaint()
    01409   {
    01410     this->LowerWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type);
    01411
    01412     this->SetWidgetLoweredState(BSW_CONVERT, _convert_signal_button);
    01413
    01414     this->SetWidgetDisabledState(BSW_DRAG_SIGNALS_DENSITY_DECREASE, _settings_client.gui.drag_signals_density == 1);
    01415     this->SetWidgetDisabledState(BSW_DRAG_SIGNALS_DENSITY_INCREASE, _settings_client.gui.drag_signals_density == 20);
    01416
    01417     this->DrawWidgets();
    01418
    01419     /* The 'hardcoded' off sets are needed because they are reused sprites. */
    01420     this->DrawSignalSprite(BSW_SEMAPHORE_NORM,  SPR_IMG_SIGNAL_SEMAPHORE_NORM,   0, 12); // xsize of sprite + 1 ==  9
    01421     this->DrawSignalSprite(BSW_SEMAPHORE_ENTRY, SPR_IMG_SIGNAL_SEMAPHORE_ENTRY, -1, 13); // xsize of sprite + 1 == 10
    01422     this->DrawSignalSprite(BSW_SEMAPHORE_EXIT,  SPR_IMG_SIGNAL_SEMAPHORE_EXIT,   0, 12); // xsize of sprite + 1 ==  9
    01423     this->DrawSignalSprite(BSW_SEMAPHORE_COMBO, SPR_IMG_SIGNAL_SEMAPHORE_COMBO,  0, 12); // xsize of sprite + 1 ==  9
    01424     this->DrawSignalSprite(BSW_SEMAPHORE_PBS,   SPR_IMG_SIGNAL_SEMAPHORE_PBS,    0, 12); // xsize of sprite + 1 ==  9
    01425     this->DrawSignalSprite(BSW_SEMAPHORE_PBS_OWAY, SPR_IMG_SIGNAL_SEMAPHORE_PBS_OWAY, -1, 13); // xsize of sprite + 1 == 10
    01426     this->DrawSignalSprite(BSW_ELECTRIC_NORM,   SPR_IMG_SIGNAL_ELECTRIC_NORM,   -1,  4);
    01427     this->DrawSignalSprite(BSW_ELECTRIC_ENTRY,  SPR_IMG_SIGNAL_ELECTRIC_ENTRY,  -2,  6);
    01428     this->DrawSignalSprite(BSW_ELECTRIC_EXIT,   SPR_IMG_SIGNAL_ELECTRIC_EXIT,   -2,  6);
    01429     this->DrawSignalSprite(BSW_ELECTRIC_COMBO,  SPR_IMG_SIGNAL_ELECTRIC_COMBO,  -2,  6);
    01430     this->DrawSignalSprite(BSW_ELECTRIC_PBS,    SPR_IMG_SIGNAL_ELECTRIC_PBS,    -1,  4);
    01431     this->DrawSignalSprite(BSW_ELECTRIC_PBS_OWAY,SPR_IMG_SIGNAL_ELECTRIC_PBS_OWAY,-2,  6);
    01432
    01433     /* Draw dragging signal density value in the BSW_DRAG_SIGNALS_DENSITY widget */
    01434     SetDParam(0, _settings_client.gui.drag_signals_density);
    01435     DrawStringCentered(this->widget[BSW_DRAG_SIGNALS_DENSITY].left + (this->widget[BSW_DRAG_SIGNALS_DENSITY].right -
    01436         this->widget[BSW_DRAG_SIGNALS_DENSITY].left) / 2 + 1,
    01437         this->widget[BSW_DRAG_SIGNALS_DENSITY].top + 2, STR_JUST_INT, TC_ORANGE);
    01438   }
    01439
    01440   virtual void OnClick(Point pt, int widget)
    01441   {
    01442     switch (widget) {
    01443       case BSW_SEMAPHORE_NORM:
    01444       case BSW_SEMAPHORE_ENTRY:
    01445       case BSW_SEMAPHORE_EXIT:
    01446       case BSW_SEMAPHORE_COMBO:
    01447       case BSW_SEMAPHORE_PBS:
    01448       case BSW_SEMAPHORE_PBS_OWAY:
    01449       case BSW_ELECTRIC_NORM:
    01450       case BSW_ELECTRIC_ENTRY:
    01451       case BSW_ELECTRIC_EXIT:
    01452       case BSW_ELECTRIC_COMBO:
    01453       case BSW_ELECTRIC_PBS:
    01454       case BSW_ELECTRIC_PBS_OWAY:
    01455         this->RaiseWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type);
    01456
    01457         _cur_signal_type = (SignalType)((uint)((widget - BSW_SEMAPHORE_NORM) % (SIGTYPE_LAST + 1)));
    01458         _cur_signal_variant = widget >= BSW_ELECTRIC_NORM ? SIG_ELECTRIC : SIG_SEMAPHORE;
    01459         break;
    01460
    01461       case BSW_CONVERT:
    01462         _convert_signal_button = !_convert_signal_button;
    01463         break;
    01464
    01465       case BSW_DRAG_SIGNALS_DENSITY_DECREASE:
    01466         if (_settings_client.gui.drag_signals_density > 1) {
    01467           _settings_client.gui.drag_signals_density--;
    01468           SetWindowDirty(FindWindowById(WC_GAME_OPTIONS, 0));
    01469         }
    01470         break;
    01471
    01472       case BSW_DRAG_SIGNALS_DENSITY_INCREASE:
    01473         if (_settings_client.gui.drag_signals_density < 20) {
    01474           _settings_client.gui.drag_signals_density++;
    01475           SetWindowDirty(FindWindowById(WC_GAME_OPTIONS, 0));
    01476         }
    01477         break;
    01478
    01479       default: break;
    01480     }
    01481
    01482     this->SetDirty();
    01483   }
    01484 };
    01485
    01487 static const Widget _signal_builder_widgets[] = {
    01488 {   WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,  10,   0,  13, STR_00C5,               STR_018B_CLOSE_WINDOW},                 // BSW_CLOSEBOX
    01489 {    WWT_CAPTION,   RESIZE_NONE,  COLOUR_DARK_GREEN,  11, 153,   0,  13, STR_SIGNAL_SELECTION,   STR_018C_WINDOW_TITLE_DRAG_THIS},       // BSW_CAPTION
    01490
    01491 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,  21,  14,  40, STR_NULL,               STR_BUILD_SIGNAL_SEMAPHORE_NORM_TIP},   // BSW_SEMAPHORE_NORM
    01492 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  22,  43,  14,  40, STR_NULL,               STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TIP},  // BSW_SEMAPHORE_ENTRY
    01493 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  44,  65,  14,  40, STR_NULL,               STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TIP},   // BSW_SEMAPHORE_EXIT
    01494 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  66,  87,  14,  40, STR_NULL,               STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TIP},  // BSW_SEMAPHORE_COMBO
    01495 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  88, 109,  14,  40, STR_NULL,               STR_BUILD_SIGNAL_SEMAPHORE_PBS_TIP},    // BSW_SEMAPHORE_PBS
    01496 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN, 110, 131,  14,  40, STR_NULL,               STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TIP},// BSW_SEMAPHORE_PBS_OWAY
    01497
    01498 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,  21,  41,  67, STR_NULL,               STR_BUILD_SIGNAL_ELECTRIC_NORM_TIP},    // BSW_ELECTRIC_NORM
    01499 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  22,  43,  41,  67, STR_NULL,               STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TIP},   // BSW_ELECTRIC_ENTRY
    01500 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  44,  65,  41,  67, STR_NULL,               STR_BUILD_SIGNAL_ELECTRIC_EXIT_TIP},    // BSW_ELECTRIC_EXIT
    01501 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  66,  87,  41,  67, STR_NULL,               STR_BUILD_SIGNAL_ELECTRIC_COMBO_TIP},   // BSW_ELECTRIC_COMBO
    01502 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  88, 109,  41,  67, STR_NULL,               STR_BUILD_SIGNAL_ELECTRIC_PBS_TIP},     // BSW_ELECTRIC_PBS
    01503 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN, 110, 131,  41,  67, STR_NULL,               STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TIP},// BSW_ELECTRIC_PBS_OWAY
    01504
    01505 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN, 132, 153,  14,  40, SPR_IMG_SIGNAL_CONVERT, STR_SIGNAL_CONVERT_TIP},                // BSW_CONVERT
    01506 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN, 132, 153,  41,  67, STR_NULL,               STR_DRAG_SIGNALS_DENSITY_TIP},          // BSW_DRAG_SIGNALS_DENSITY
    01507 { WWT_PUSHIMGBTN,   RESIZE_NONE,  COLOUR_GREY,       134, 142,  54,  65, SPR_ARROW_LEFT,         STR_DRAG_SIGNALS_DENSITY_DECREASE_TIP}, // BSW_DRAG_SIGNALS_DENSITY_DECREASE
    01508 { WWT_PUSHIMGBTN,   RESIZE_NONE,  COLOUR_GREY,       143, 151,  54,  65, SPR_ARROW_RIGHT,        STR_DRAG_SIGNALS_DENSITY_INCREASE_TIP}, // BSW_DRAG_SIGNALS_DENSITY_INCREASE
    01509
    01510 {   WIDGETS_END},
    01511 };
    01512
    01514 static const WindowDesc _signal_builder_desc = {
    01515   WDP_AUTO, WDP_AUTO, 154, 68, 154, 68,
    01516   WC_BUILD_SIGNAL, WC_BUILD_TOOLBAR,
    01517   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_CONSTRUCTION,
    01518   _signal_builder_widgets,
    01519 };
    01520
    01524 static void ShowSignalBuilder(Window *parent)
    01525 {
    01526   new BuildSignalWindow(&_signal_builder_desc, parent);
    01527 }
    01528
    01529 struct BuildRailDepotWindow : public PickerWindowBase {
    01530 private:
    01532   enum BuildRailDepotWidgets {
    01533     BRDW_CLOSEBOX = 0,
    01534     BRDW_CAPTION,
    01535     BRDW_BACKGROUND,
    01536     BRDW_DEPOT_NE,
    01537     BRDW_DEPOT_SE,
    01538     BRDW_DEPOT_SW,
    01539     BRDW_DEPOT_NW,
    01540   };
    01541
    01542 public:
    01543   BuildRailDepotWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(desc, parent)
    01544   {
    01545     this->LowerWidget(_build_depot_direction + BRDW_DEPOT_NE);
    01546     this->FindWindowPlacementAndResize(desc);
    01547   }
    01548
    01549   virtual void OnPaint()
    01550   {
    01551     this->DrawWidgets();
    01552
    01553     DrawTrainDepotSprite(70, 17, DIAGDIR_NE, _cur_railtype);
    01554     DrawTrainDepotSprite(70, 69, DIAGDIR_SE, _cur_railtype);
    01555     DrawTrainDepotSprite( 2, 69, DIAGDIR_SW, _cur_railtype);
    01556     DrawTrainDepotSprite( 2, 17, DIAGDIR_NW, _cur_railtype);
    01557   }
    01558
    01559   virtual void OnClick(Point pt, int widget)
    01560   {
    01561     switch (widget) {
    01562       case BRDW_DEPOT_NE:
    01563       case BRDW_DEPOT_SE:
    01564       case BRDW_DEPOT_SW:
    01565       case BRDW_DEPOT_NW:
    01566         this->RaiseWidget(_build_depot_direction + BRDW_DEPOT_NE);
    01567         _build_depot_direction = (DiagDirection)(widget - BRDW_DEPOT_NE);
    01568         this->LowerWidget(_build_depot_direction + BRDW_DEPOT_NE);
    01569         SndPlayFx(SND_15_BEEP);
    01570         this->SetDirty();
    01571         break;
    01572     }
    01573   }
    01574 };
    01575
    01577 static const Widget _build_depot_widgets[] = {
    01578 {   WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,    10,     0,    13, STR_00C5,                         STR_018B_CLOSE_WINDOW},                     // BRDW_CLOSEBOX
    01579 {    WWT_CAPTION,   RESIZE_NONE,  COLOUR_DARK_GREEN,  11,   139,     0,    13, STR_1014_TRAIN_DEPOT_ORIENTATION, STR_018C_WINDOW_TITLE_DRAG_THIS},           // BRDW_CAPTION
    01580 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,   139,    14,   121, 0x0,                              STR_NULL},                                  // BRDW_BACKGROUND
    01581 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,        71,   136,    17,    66, 0x0,                              STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO}, // BRDW_DEPOT_NE
    01582 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,        71,   136,    69,   118, 0x0,                              STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO}, // BRDW_DEPOT_SE
    01583 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,         3,    68,    69,   118, 0x0,                              STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO}, // BRDW_DEPOT_SW
    01584 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,         3,    68,    17,    66, 0x0,                              STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO}, // BRDW_DEPOT_NW
    01585 {   WIDGETS_END},
    01586 };
    01587
    01588 static const WindowDesc _build_depot_desc = {
    01589   WDP_AUTO, WDP_AUTO, 140, 122, 140, 122,
    01590   WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
    01591   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_CONSTRUCTION,
    01592   _build_depot_widgets,
    01593 };
    01594
    01595 static void ShowBuildTrainDepotPicker(Window *parent)
    01596 {
    01597   new BuildRailDepotWindow(&_build_depot_desc, parent);
    01598 }
    01599
    01600 struct BuildRailWaypointWindow : PickerWindowBase {
    01601 private:
    01603   enum BuildRailWaypointWidgets {
    01604     BRWW_CLOSEBOX = 0,
    01605     BRWW_CAPTION,
    01606     BRWW_BACKGROUND,
    01607     BRWW_WAYPOINT_1,
    01608     BRWW_WAYPOINT_2,
    01609     BRWW_WAYPOINT_3,
    01610     BRWW_WAYPOINT_4,
    01611     BRWW_WAYPOINT_5,
    01612     BRWW_SCROLL,
    01613   };
    01614
    01615 public:
    01616   BuildRailWaypointWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(desc, parent)
    01617   {
    01618     this->hscroll.cap = 5;
    01619     this->hscroll.count = _waypoint_count;
    01620     this->FindWindowPlacementAndResize(desc);
    01621   };
    01622
    01623   virtual void OnPaint()
    01624   {
    01625     uint i;
    01626
    01627     for (i = 0; i < this->hscroll.cap; i++) {
    01628       this->SetWidgetLoweredState(i + BRWW_WAYPOINT_1, (this->hscroll.pos + i) == _cur_waypoint_type);
    01629     }
    01630
    01631     this->DrawWidgets();
    01632
    01633     for (i = 0; i < this->hscroll.cap; i++) {
    01634       if (this->hscroll.pos + i < this->hscroll.count) {
    01635         const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, this->hscroll.pos + i);
    01636
    01637         DrawWaypointSprite(2 + i * 68, 25, this->hscroll.pos + i, _cur_railtype);
    01638
    01639         if (statspec != NULL &&
    01640             HasBit(statspec->callbackmask, CBM_STATION_AVAIL) &&
    01641             GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) {
    01642           GfxFillRect(4 + i * 68, 18, 67 + i * 68, 75, 0, FILLRECT_CHECKER);
    01643         }
    01644       }
    01645     }
    01646   }
    01647
    01648   virtual void OnClick(Point pt, int widget)
    01649   {
    01650     switch (widget) {
    01651       case BRWW_WAYPOINT_1:
    01652       case BRWW_WAYPOINT_2:
    01653       case BRWW_WAYPOINT_3:
    01654       case BRWW_WAYPOINT_4:
    01655       case BRWW_WAYPOINT_5: {
    01656         byte type = widget - BRWW_WAYPOINT_1 + this->hscroll.pos;
    01657
    01658         /* Check station availability callback */
    01659         const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, type);
    01660         if (statspec != NULL &&
    01661             HasBit(statspec->callbackmask, CBM_STATION_AVAIL) &&
    01662             GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) return;
    01663
    01664         _cur_waypoint_type = type;
    01665         SndPlayFx(SND_15_BEEP);
    01666         this->SetDirty();
    01667         break;
    01668       }
    01669     }
    01670   }
    01671 };
    01672
    01674 static const Widget _build_waypoint_widgets[] = {
    01675 {   WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN,     0,    10,     0,    13, STR_00C5,     STR_018B_CLOSE_WINDOW},            // BRWW_CLOSEBOX
    01676 {    WWT_CAPTION,   RESIZE_NONE,  COLOUR_DARK_GREEN,    11,   343,     0,    13, STR_WAYPOINT, STR_018C_WINDOW_TITLE_DRAG_THIS},  // BRWW_CAPTION
    01677 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,     0,   343,    14,    91, 0x0,          STR_NULL},                         // BRWW_BACKGROUND
    01678
    01679 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,     3,    68,    17,    76, 0x0,          STR_WAYPOINT_GRAPHICS_TIP},        // BRWW_WAYPOINT_1
    01680 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,    71,   136,    17,    76, 0x0,          STR_WAYPOINT_GRAPHICS_TIP},        // BRWW_WAYPOINT_2
    01681 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   139,   204,    17,    76, 0x0,          STR_WAYPOINT_GRAPHICS_TIP},        // BRWW_WAYPOINT_3
    01682 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   207,   272,    17,    76, 0x0,          STR_WAYPOINT_GRAPHICS_TIP},        // BRWW_WAYPOINT_4
    01683 {      WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,   275,   340,    17,    76, 0x0,          STR_WAYPOINT_GRAPHICS_TIP},        // BRWW_WAYPOINT_5
    01684
    01685 { WWT_HSCROLLBAR,   RESIZE_NONE,  COLOUR_DARK_GREEN,     1,   343,     80,    91, 0x0,          STR_HSCROLL_BAR_SCROLLS_LIST},     // BRWW_SCROLL
    01686 {    WIDGETS_END},
    01687 };
    01688
    01689 static const WindowDesc _build_waypoint_desc = {
    01690   WDP_AUTO, WDP_AUTO, 344, 92, 344, 92,
    01691   WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
    01692   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_CONSTRUCTION,
    01693   _build_waypoint_widgets,
    01694 };
    01695
    01696 static void ShowBuildWaypointPicker(Window *parent)
    01697 {
    01698   new BuildRailWaypointWindow(&_build_waypoint_desc, parent);
    01699 }
    01700
    01704 void InitializeRailGui()
    01705 {
    01706   _build_depot_direction = DIAGDIR_NW;
    01707 }
    01708
    01713 void ReinitGuiAfterToggleElrail(bool disable)
    01714 {
    01715   extern RailType _last_built_railtype;
    01716   if (disable && _last_built_railtype == RAILTYPE_ELECTRIC) {
    01717     Window *w;
    01718     _last_built_railtype = _cur_railtype = RAILTYPE_RAIL;
    01719     w = FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_RAIL);
    01720     if (w != NULL) {
    01721       SetupRailToolbar(_cur_railtype, w);
    01722       w->SetDirty();
    01723     }
    01724   }
    01725   MarkWholeScreenDirty();
    01726 }
    01727
    01729 static void SetDefaultRailGui()
    01730 {
    01731   if (_local_company == COMPANY_SPECTATOR || !IsValidCompanyID(_local_company)) return;
    01732
    01733   extern RailType _last_built_railtype;
    01734   RailType rt = (RailType)_settings_client.gui.default_rail_type;
    01735   if (rt >= RAILTYPE_END) {
    01736     if (rt == RAILTYPE_END + 2) {
    01737       /* Find the most used rail type */
    01738       RailType count[RAILTYPE_END];
    01739       memset(count, 0, sizeof(count));
    01740       for (TileIndex t = 0; t < MapSize(); t++) {
    01741         if (IsTileType(t, MP_RAILWAY) || IsLevelCrossingTile(t) || IsRailwayStationTile(t) ||
    01742             (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL)) {
    01743           count[GetRailType(t)]++;
    01744         }
    01745       }
    01746
    01747       rt = RAILTYPE_RAIL;
    01748       for (RailType r = RAILTYPE_ELECTRIC; r < RAILTYPE_END; r++) {
    01749         if (count[r] >= count[rt]) rt = r;
    01750       }
    01751
    01752       /* No rail, just get the first available one */
    01753       if (count[rt] == 0) rt = RAILTYPE_END;
    01754     }
    01755     switch (rt) {
    01756       case RAILTYPE_END + 0:
    01757         rt = RAILTYPE_RAIL;
    01758         while (rt < RAILTYPE_END && !HasRailtypeAvail(_local_company, rt)) rt++;
    01759         break;
    01760
    01761       case RAILTYPE_END + 1:
    01762         rt = GetBestRailtype(_local_company);
    01763         break;
    01764
    01765       default:
    01766         break;
    01767     }
    01768   }
    01769
    01770   _last_built_railtype = _cur_railtype = rt;
    01771   Window *w = FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_RAIL);
    01772   if (w != NULL) {
    01773     SetupRailToolbar(_cur_railtype, w);
    01774     w->SetDirty();
    01775   }
    01776 }
    01777
    01784 bool ResetSignalVariant(int32 = 0)
    01785 {
    01786   SignalVariant new_variant = (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC);
    01787
    01788   if (new_variant != _cur_signal_variant) {
    01789     Window *w = FindWindowById(WC_BUILD_SIGNAL, 0);
    01790     if (w != NULL) {
    01791       w->SetDirty();
    01792       w->RaiseWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type);
    01793     }
    01794     _cur_signal_variant = new_variant;
    01795   }
    01796
    01797   return true;
    01798 }
    01799
    01803 void InitializeRailGUI()
    01804 {
    01805   SetDefaultRailGui();
    01806
    01807   _convert_signal_button = false;
    01808   _cur_signal_type = _default_signal_type[_settings_client.gui.default_signal_type];
    01809   ResetSignalVariant();
    01810 }