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 }

Generated on Wed Jul 15 20:36:01 2009 for OpenTTD by  doxygen 1.5.6