00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "gui.h"
00014 #include "window_gui.h"
00015 #include "station_gui.h"
00016 #include "terraform_gui.h"
00017 #include "viewport_func.h"
00018 #include "command_func.h"
00019 #include "waypoint_func.h"
00020 #include "newgrf_station.h"
00021 #include "company_base.h"
00022 #include "strings_func.h"
00023 #include "functions.h"
00024 #include "window_func.h"
00025 #include "date_func.h"
00026 #include "sound_func.h"
00027 #include "company_func.h"
00028 #include "widgets/dropdown_type.h"
00029 #include "tunnelbridge.h"
00030 #include "tilehighlight_func.h"
00031 #include "spritecache.h"
00032 #include "core/geometry_func.hpp"
00033
00034 #include "station_map.h"
00035 #include "tunnelbridge_map.h"
00036
00037 #include "table/sprites.h"
00038 #include "table/strings.h"
00039
00040 static RailType _cur_railtype;
00041 static bool _remove_button_clicked;
00042 static DiagDirection _build_depot_direction;
00043 static byte _waypoint_count = 1;
00044 static byte _cur_waypoint_type;
00045 static bool _convert_signal_button;
00046 static SignalVariant _cur_signal_variant;
00047 static SignalType _cur_signal_type;
00048
00049
00050 static const SignalType _default_signal_type[] = {SIGTYPE_NORMAL, SIGTYPE_PBS, SIGTYPE_PBS_ONEWAY};
00051
00052 struct RailStationGUISettings {
00053 Axis orientation;
00054
00055 bool newstations;
00056 StationClassIDByte station_class;
00057 byte station_type;
00058 byte station_count;
00059 };
00060 static RailStationGUISettings _railstation;
00061
00062
00063 static void HandleStationPlacement(TileIndex start, TileIndex end);
00064 static void ShowBuildTrainDepotPicker(Window *parent);
00065 static void ShowBuildWaypointPicker(Window *parent);
00066 static void ShowStationBuilder(Window *parent);
00067 static void ShowSignalBuilder(Window *parent);
00068
00069 void CcPlaySound1E(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
00070 {
00071 if (result.Succeeded()) SndPlayTileFx(SND_20_SPLAT_2, tile);
00072 }
00073
00074 static void GenericPlaceRail(TileIndex tile, int cmd)
00075 {
00076 DoCommandP(tile, _cur_railtype, cmd,
00077 _remove_button_clicked ?
00078 CMD_REMOVE_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) :
00079 CMD_BUILD_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK),
00080 CcPlaySound1E
00081 );
00082 }
00083
00084 static void PlaceRail_N(TileIndex tile)
00085 {
00086 VpStartPlaceSizing(tile, VPM_FIX_VERTICAL | VPM_RAILDIRS, DDSP_PLACE_RAIL);
00087 }
00088
00089 static void PlaceRail_NE(TileIndex tile)
00090 {
00091 VpStartPlaceSizing(tile, VPM_FIX_Y | VPM_RAILDIRS, DDSP_PLACE_RAIL);
00092 }
00093
00094 static void PlaceRail_E(TileIndex tile)
00095 {
00096 VpStartPlaceSizing(tile, VPM_FIX_HORIZONTAL | VPM_RAILDIRS, DDSP_PLACE_RAIL);
00097 }
00098
00099 static void PlaceRail_NW(TileIndex tile)
00100 {
00101 VpStartPlaceSizing(tile, VPM_FIX_X | VPM_RAILDIRS, DDSP_PLACE_RAIL);
00102 }
00103
00104 static void PlaceRail_AutoRail(TileIndex tile)
00105 {
00106 VpStartPlaceSizing(tile, VPM_RAILDIRS, DDSP_PLACE_RAIL);
00107 }
00108
00115 static void PlaceExtraDepotRail(TileIndex tile, uint16 extra)
00116 {
00117 if (GetRailTileType(tile) != RAIL_TILE_NORMAL) return;
00118 if ((GetTrackBits(tile) & GB(extra, 8, 8)) == 0) return;
00119
00120 DoCommandP(tile, _cur_railtype, extra & 0xFF, CMD_BUILD_SINGLE_RAIL);
00121 }
00122
00124 static const uint16 _place_depot_extra[12] = {
00125 0x0604, 0x2102, 0x1202, 0x0505,
00126 0x2400, 0x2801, 0x1800, 0x1401,
00127 0x2203, 0x0904, 0x0A05, 0x1103,
00128 };
00129
00130
00131 void CcRailDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
00132 {
00133 if (result.Failed()) return;
00134
00135 DiagDirection dir = (DiagDirection)p2;
00136
00137 SndPlayTileFx(SND_20_SPLAT_2, tile);
00138 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
00139
00140 tile += TileOffsByDiagDir(dir);
00141
00142 if (IsTileType(tile, MP_RAILWAY)) {
00143 PlaceExtraDepotRail(tile, _place_depot_extra[dir]);
00144 PlaceExtraDepotRail(tile, _place_depot_extra[dir + 4]);
00145 PlaceExtraDepotRail(tile, _place_depot_extra[dir + 8]);
00146 }
00147 }
00148
00149 static void PlaceRail_Depot(TileIndex tile)
00150 {
00151 DoCommandP(tile, _cur_railtype, _build_depot_direction,
00152 CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT),
00153 CcRailDepot);
00154 }
00155
00156 static void PlaceRail_Waypoint(TileIndex tile)
00157 {
00158 if (_remove_button_clicked) {
00159 VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_REMOVE_STATION);
00160 return;
00161 }
00162
00163 Axis axis = GetAxisForNewWaypoint(tile);
00164 if (IsValidAxis(axis)) {
00165
00166 VpStartPlaceSizing(tile, axis == AXIS_X ? VPM_FIX_X : VPM_FIX_Y, DDSP_BUILD_STATION);
00167 } else {
00168
00169
00170 DoCommandP(tile, 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16, CMD_BUILD_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT));
00171 }
00172 }
00173
00174 void CcStation(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
00175 {
00176 if (result.Failed()) return;
00177
00178 SndPlayTileFx(SND_20_SPLAT_2, tile);
00179
00180 if (_railstation.station_class == STAT_CLASS_DFLT && _railstation.station_type == 0 && !_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
00181 }
00182
00183 static void PlaceRail_Station(TileIndex tile)
00184 {
00185 if (_remove_button_clicked) {
00186 VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_REMOVE_STATION);
00187 VpSetPlaceSizingLimit(-1);
00188 } else if (_settings_client.gui.station_dragdrop) {
00189 VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_STATION);
00190 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
00191 } else {
00192 uint32 p1 = _cur_railtype | _railstation.orientation << 4 | _settings_client.gui.station_numtracks << 8 | _settings_client.gui.station_platlength << 16 | _ctrl_pressed << 24;
00193 uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16;
00194
00195 int w = _settings_client.gui.station_numtracks;
00196 int h = _settings_client.gui.station_platlength;
00197 if (!_railstation.orientation) Swap(w, h);
00198
00199 CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" };
00200 ShowSelectStationIfNeeded(cmdcont, TileArea(tile, w, h));
00201 }
00202 }
00203
00209 static void GenericPlaceSignals(TileIndex tile)
00210 {
00211 TrackBits trackbits = TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0));
00212
00213 if (trackbits & TRACK_BIT_VERT) {
00214 trackbits = (_tile_fract_coords.x <= _tile_fract_coords.y) ? TRACK_BIT_RIGHT : TRACK_BIT_LEFT;
00215 }
00216
00217 if (trackbits & TRACK_BIT_HORZ) {
00218 trackbits = (_tile_fract_coords.x + _tile_fract_coords.y <= 15) ? TRACK_BIT_UPPER : TRACK_BIT_LOWER;
00219 }
00220
00221 Track track = FindFirstTrack(trackbits);
00222
00223 if (_remove_button_clicked) {
00224 DoCommandP(tile, track, 0, CMD_REMOVE_SIGNALS | CMD_MSG(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM), CcPlaySound1E);
00225 } else {
00226 const Window *w = FindWindowById(WC_BUILD_SIGNAL, 0);
00227
00228
00229 static const uint cycle_bounds[] = {SIGTYPE_NORMAL | (SIGTYPE_LAST_NOPBS << 3), SIGTYPE_PBS | (SIGTYPE_LAST << 3), SIGTYPE_NORMAL | (SIGTYPE_LAST << 3)};
00230
00231
00232 uint32 p1 = track;
00233
00234 if (w != NULL) {
00235
00236 SB(p1, 3, 1, _ctrl_pressed);
00237 SB(p1, 4, 1, _cur_signal_variant);
00238 SB(p1, 5, 3, _cur_signal_type);
00239 SB(p1, 8, 1, _convert_signal_button);
00240 SB(p1, 9, 6, cycle_bounds[_settings_client.gui.cycle_signal_types]);
00241 } else {
00242 SB(p1, 3, 1, _ctrl_pressed);
00243 SB(p1, 4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
00244 SB(p1, 5, 3, _default_signal_type[_settings_client.gui.default_signal_type]);
00245 SB(p1, 8, 1, 0);
00246 SB(p1, 9, 6, cycle_bounds[_settings_client.gui.cycle_signal_types]);
00247 }
00248
00249 DoCommandP(tile, p1, 0, CMD_BUILD_SIGNALS |
00250 CMD_MSG((w != NULL && _convert_signal_button) ? STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE),
00251 CcPlaySound1E);
00252 }
00253 }
00254
00255 static void PlaceRail_Bridge(TileIndex tile)
00256 {
00257 VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE);
00258 }
00259
00261 void CcBuildRailTunnel(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
00262 {
00263 if (result.Succeeded()) {
00264 SndPlayTileFx(SND_20_SPLAT_2, tile);
00265 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
00266 } else {
00267 SetRedErrorSquare(_build_tunnel_endtile);
00268 }
00269 }
00270
00271 static void PlaceRail_Tunnel(TileIndex tile)
00272 {
00273 DoCommandP(tile, _cur_railtype, 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel);
00274 }
00275
00276 static void PlaceRail_ConvertRail(TileIndex tile)
00277 {
00278 VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CONVERT_RAIL);
00279 }
00280
00281 static void PlaceRail_AutoSignals(TileIndex tile)
00282 {
00283 VpStartPlaceSizing(tile, VPM_SIGNALDIRS, DDSP_BUILD_SIGNALS);
00284 }
00285
00286
00288 enum RailToolbarWidgets {
00289 RTW_CAPTION,
00290 RTW_BUILD_NS,
00291 RTW_BUILD_X,
00292 RTW_BUILD_EW,
00293 RTW_BUILD_Y,
00294 RTW_AUTORAIL,
00295 RTW_DEMOLISH,
00296 RTW_BUILD_DEPOT,
00297 RTW_BUILD_WAYPOINT,
00298 RTW_BUILD_STATION,
00299 RTW_BUILD_SIGNALS,
00300 RTW_BUILD_BRIDGE,
00301 RTW_BUILD_TUNNEL,
00302 RTW_REMOVE,
00303 RTW_CONVERT_RAIL,
00304 };
00305
00306
00310 static void ToggleRailButton_Remove(Window *w)
00311 {
00312 DeleteWindowById(WC_SELECT_STATION, 0);
00313 w->ToggleWidgetLoweredState(RTW_REMOVE);
00314 w->SetWidgetDirty(RTW_REMOVE);
00315 _remove_button_clicked = w->IsWidgetLowered(RTW_REMOVE);
00316 SetSelectionRed(_remove_button_clicked);
00317 }
00318
00323 static bool RailToolbar_CtrlChanged(Window *w)
00324 {
00325 if (w->IsWidgetDisabled(RTW_REMOVE)) return false;
00326
00327
00328 for (uint i = RTW_BUILD_NS; i <= RTW_BUILD_STATION; i++) {
00329 if ((i <= RTW_AUTORAIL || i >= RTW_BUILD_WAYPOINT) && w->IsWidgetLowered(i)) {
00330 ToggleRailButton_Remove(w);
00331 return true;
00332 }
00333 }
00334
00335 return false;
00336 }
00337
00338
00344 static void BuildRailClick_N(Window *w)
00345 {
00346 HandlePlacePushButton(w, RTW_BUILD_NS, GetRailTypeInfo(_cur_railtype)->cursor.rail_ns, HT_LINE | HT_DIR_VL, PlaceRail_N);
00347 }
00348
00354 static void BuildRailClick_NE(Window *w)
00355 {
00356 HandlePlacePushButton(w, RTW_BUILD_X, GetRailTypeInfo(_cur_railtype)->cursor.rail_swne, HT_LINE | HT_DIR_X, PlaceRail_NE);
00357 }
00358
00364 static void BuildRailClick_E(Window *w)
00365 {
00366 HandlePlacePushButton(w, RTW_BUILD_EW, GetRailTypeInfo(_cur_railtype)->cursor.rail_ew, HT_LINE | HT_DIR_HL, PlaceRail_E);
00367 }
00368
00374 static void BuildRailClick_NW(Window *w)
00375 {
00376 HandlePlacePushButton(w, RTW_BUILD_Y, GetRailTypeInfo(_cur_railtype)->cursor.rail_nwse, HT_LINE | HT_DIR_Y, PlaceRail_NW);
00377 }
00378
00384 static void BuildRailClick_AutoRail(Window *w)
00385 {
00386 HandlePlacePushButton(w, RTW_AUTORAIL, GetRailTypeInfo(_cur_railtype)->cursor.autorail, HT_RAIL, PlaceRail_AutoRail);
00387 }
00388
00394 static void BuildRailClick_Demolish(Window *w)
00395 {
00396 HandlePlacePushButton(w, RTW_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT, PlaceProc_DemolishArea);
00397 }
00398
00404 static void BuildRailClick_Depot(Window *w)
00405 {
00406 if (HandlePlacePushButton(w, RTW_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, HT_RECT, PlaceRail_Depot)) {
00407 ShowBuildTrainDepotPicker(w);
00408 }
00409 }
00410
00417 static void BuildRailClick_Waypoint(Window *w)
00418 {
00419 _waypoint_count = GetNumCustomStations(STAT_CLASS_WAYP);
00420 if (HandlePlacePushButton(w, RTW_BUILD_WAYPOINT, SPR_CURSOR_WAYPOINT, HT_RECT, PlaceRail_Waypoint) &&
00421 _waypoint_count > 1) {
00422 ShowBuildWaypointPicker(w);
00423 }
00424 }
00425
00431 static void BuildRailClick_Station(Window *w)
00432 {
00433 if (HandlePlacePushButton(w, RTW_BUILD_STATION, SPR_CURSOR_RAIL_STATION, HT_RECT, PlaceRail_Station)) ShowStationBuilder(w);
00434 }
00435
00442 static void BuildRailClick_AutoSignals(Window *w)
00443 {
00444 if (_settings_client.gui.enable_signal_gui != _ctrl_pressed) {
00445 if (HandlePlacePushButton(w, RTW_BUILD_SIGNALS, ANIMCURSOR_BUILDSIGNALS, HT_RECT, PlaceRail_AutoSignals)) ShowSignalBuilder(w);
00446 } else {
00447 HandlePlacePushButton(w, RTW_BUILD_SIGNALS, ANIMCURSOR_BUILDSIGNALS, HT_RECT, PlaceRail_AutoSignals);
00448 }
00449 }
00450
00456 static void BuildRailClick_Bridge(Window *w)
00457 {
00458 HandlePlacePushButton(w, RTW_BUILD_BRIDGE, SPR_CURSOR_BRIDGE, HT_RECT, PlaceRail_Bridge);
00459 }
00460
00466 static void BuildRailClick_Tunnel(Window *w)
00467 {
00468 HandlePlacePushButton(w, RTW_BUILD_TUNNEL, GetRailTypeInfo(_cur_railtype)->cursor.tunnel, HT_SPECIAL, PlaceRail_Tunnel);
00469 }
00470
00476 static void BuildRailClick_Remove(Window *w)
00477 {
00478 if (w->IsWidgetDisabled(RTW_REMOVE)) return;
00479 ToggleRailButton_Remove(w);
00480 SndPlayFx(SND_15_BEEP);
00481
00482
00483 if (w->IsWidgetLowered(RTW_BUILD_STATION)) {
00484 if (_remove_button_clicked) {
00485
00486 if (!_settings_client.gui.station_dragdrop) {
00487 SetTileSelectSize(1, 1);
00488 } else {
00489 VpSetPlaceSizingLimit(-1);
00490 }
00491 } else {
00492
00493 if (!_settings_client.gui.station_dragdrop) {
00494 int x = _settings_client.gui.station_numtracks;
00495 int y = _settings_client.gui.station_platlength;
00496 if (_railstation.orientation == 0) Swap(x, y);
00497 SetTileSelectSize(x, y);
00498 } else {
00499 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
00500 }
00501 }
00502 }
00503 }
00504
00511 static void BuildRailClick_Convert(Window *w)
00512 {
00513 HandlePlacePushButton(w, RTW_CONVERT_RAIL, GetRailTypeInfo(_cur_railtype)->cursor.convert, HT_RECT, PlaceRail_ConvertRail);
00514 }
00515
00516
00517 static void DoRailroadTrack(int mode)
00518 {
00519 DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 4),
00520 _remove_button_clicked ?
00521 CMD_REMOVE_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) :
00522 CMD_BUILD_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK)
00523 );
00524 }
00525
00526 static void HandleAutodirPlacement()
00527 {
00528 TileHighlightData *thd = &_thd;
00529 int trackstat = thd->drawstyle & 0xF;
00530
00531 if (thd->drawstyle & HT_RAIL) {
00532 GenericPlaceRail(TileVirtXY(thd->selend.x, thd->selend.y), trackstat);
00533 return;
00534 }
00535
00536 DoRailroadTrack(trackstat);
00537 }
00538
00545 static void HandleAutoSignalPlacement()
00546 {
00547 TileHighlightData *thd = &_thd;
00548 uint32 p2 = GB(thd->drawstyle, 0, 3);
00549
00550 if (thd->drawstyle == HT_RECT) {
00551 GenericPlaceSignals(TileVirtXY(thd->selend.x, thd->selend.y));
00552 return;
00553 }
00554
00555 const Window *w = FindWindowById(WC_BUILD_SIGNAL, 0);
00556
00557 if (w != NULL) {
00558
00559 SB(p2, 3, 1, 0);
00560 SB(p2, 4, 1, _cur_signal_variant);
00561 SB(p2, 6, 1, _ctrl_pressed);
00562 SB(p2, 7, 3, _cur_signal_type);
00563 SB(p2, 24, 8, _settings_client.gui.drag_signals_density);
00564 } else {
00565 SB(p2, 3, 1, 0);
00566 SB(p2, 4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
00567 SB(p2, 6, 1, _ctrl_pressed);
00568 SB(p2, 7, 3, _default_signal_type[_settings_client.gui.default_signal_type]);
00569 SB(p2, 24, 8, _settings_client.gui.drag_signals_density);
00570 }
00571
00572
00573
00574 DoCommandP(
00575 TileVirtXY(thd->selstart.x, thd->selstart.y),
00576 TileVirtXY(thd->selend.x, thd->selend.y),
00577 p2,
00578 _remove_button_clicked ?
00579 CMD_REMOVE_SIGNAL_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM) :
00580 CMD_BUILD_SIGNAL_TRACK | CMD_MSG(STR_ERROR_CAN_T_BUILD_SIGNALS_HERE),
00581 CcPlaySound1E);
00582 }
00583
00584
00585 typedef void OnButtonClick(Window *w);
00586
00588 struct RailBuildingGUIButtonData {
00589 uint16 keycode;
00590 OnButtonClick *click_proc;
00591 };
00592
00597 static const RailBuildingGUIButtonData _rail_build_button_data[] = {
00598 {'1', BuildRailClick_N },
00599 {'2', BuildRailClick_NE },
00600 {'3', BuildRailClick_E },
00601 {'4', BuildRailClick_NW },
00602 {'5', BuildRailClick_AutoRail },
00603 {'6', BuildRailClick_Demolish },
00604 {'7', BuildRailClick_Depot },
00605 {'8', BuildRailClick_Waypoint },
00606 {'9', BuildRailClick_Station },
00607 {'S', BuildRailClick_AutoSignals},
00608 {'B', BuildRailClick_Bridge },
00609 {'T', BuildRailClick_Tunnel },
00610 {'R', BuildRailClick_Remove },
00611 {'C', BuildRailClick_Convert }
00612 };
00613
00619 struct BuildRailToolbarWindow : Window {
00620 BuildRailToolbarWindow(const WindowDesc *desc, WindowNumber window_number, RailType railtype) : Window()
00621 {
00622 this->InitNested(desc);
00623 this->SetupRailToolbar(railtype);
00624 this->DisableWidget(RTW_REMOVE);
00625
00626 if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
00627 }
00628
00629 ~BuildRailToolbarWindow()
00630 {
00631 if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false);
00632 }
00633
00637 void SetupRailToolbar(RailType railtype)
00638 {
00639 const RailtypeInfo *rti = GetRailTypeInfo(railtype);
00640
00641 assert(railtype < RAILTYPE_END);
00642 this->GetWidget<NWidgetCore>(RTW_CAPTION)->widget_data = rti->strings.toolbar_caption;
00643 this->GetWidget<NWidgetCore>(RTW_BUILD_NS)->widget_data = rti->gui_sprites.build_ns_rail;
00644 this->GetWidget<NWidgetCore>(RTW_BUILD_X)->widget_data = rti->gui_sprites.build_x_rail;
00645 this->GetWidget<NWidgetCore>(RTW_BUILD_EW)->widget_data = rti->gui_sprites.build_ew_rail;
00646 this->GetWidget<NWidgetCore>(RTW_BUILD_Y)->widget_data = rti->gui_sprites.build_y_rail;
00647 this->GetWidget<NWidgetCore>(RTW_AUTORAIL)->widget_data = rti->gui_sprites.auto_rail;
00648 this->GetWidget<NWidgetCore>(RTW_BUILD_DEPOT)->widget_data = rti->gui_sprites.build_depot;
00649 this->GetWidget<NWidgetCore>(RTW_CONVERT_RAIL)->widget_data = rti->gui_sprites.convert_rail;
00650 this->GetWidget<NWidgetCore>(RTW_BUILD_TUNNEL)->widget_data = rti->gui_sprites.build_tunnel;
00651 }
00652
00656 void ModifyRailType(RailType railtype)
00657 {
00658 this->SetupRailToolbar(railtype);
00659 this->ReInit();
00660 }
00661
00662 void UpdateRemoveWidgetStatus(int clicked_widget)
00663 {
00664 switch (clicked_widget) {
00665 case RTW_REMOVE:
00666
00667
00668 return;
00669 break;
00670 case RTW_BUILD_NS:
00671 case RTW_BUILD_X:
00672 case RTW_BUILD_EW:
00673 case RTW_BUILD_Y:
00674 case RTW_AUTORAIL:
00675 case RTW_BUILD_WAYPOINT:
00676 case RTW_BUILD_STATION:
00677 case RTW_BUILD_SIGNALS:
00678
00679
00680 this->SetWidgetDisabledState(RTW_REMOVE, !this->IsWidgetLowered(clicked_widget));
00681 break;
00682
00683 default:
00684
00685
00686 this->DisableWidget(RTW_REMOVE);
00687 this->RaiseWidget(RTW_REMOVE);
00688 break;
00689 }
00690 }
00691
00692 virtual void OnPaint()
00693 {
00694 this->DrawWidgets();
00695 }
00696
00697 virtual void OnClick(Point pt, int widget)
00698 {
00699 if (widget >= RTW_BUILD_NS) {
00700 _remove_button_clicked = false;
00701 _rail_build_button_data[widget - RTW_BUILD_NS].click_proc(this);
00702 }
00703 this->UpdateRemoveWidgetStatus(widget);
00704 if (_ctrl_pressed) RailToolbar_CtrlChanged(this);
00705 }
00706
00707 virtual EventState OnKeyPress(uint16 key, uint16 keycode)
00708 {
00709 EventState state = ES_NOT_HANDLED;
00710 for (uint8 i = 0; i != lengthof(_rail_build_button_data); i++) {
00711 if (keycode == _rail_build_button_data[i].keycode) {
00712 _remove_button_clicked = false;
00713 _rail_build_button_data[i].click_proc(this);
00714 this->UpdateRemoveWidgetStatus(i + RTW_BUILD_NS);
00715 if (_ctrl_pressed) RailToolbar_CtrlChanged(this);
00716 state = ES_HANDLED;
00717 break;
00718 }
00719 }
00720 MarkTileDirtyByTile(TileVirtXY(_thd.pos.x, _thd.pos.y));
00721 return state;
00722 }
00723
00724 virtual void OnPlaceObject(Point pt, TileIndex tile)
00725 {
00726 _place_proc(tile);
00727 }
00728
00729 virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
00730 {
00731
00732 if (FindWindowById(WC_BUILD_SIGNAL, 0) != NULL && _convert_signal_button && this->IsWidgetLowered(RTW_BUILD_SIGNALS)) return;
00733
00734 VpSelectTilesWithMethod(pt.x, pt.y, select_method);
00735 }
00736
00737 virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
00738 {
00739 if (pt.x != -1) {
00740 switch (select_proc) {
00741 default: NOT_REACHED();
00742 case DDSP_BUILD_BRIDGE:
00743 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
00744 ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_RAIL, _cur_railtype);
00745 break;
00746
00747 case DDSP_PLACE_RAIL:
00748 HandleAutodirPlacement();
00749 break;
00750
00751 case DDSP_BUILD_SIGNALS:
00752 HandleAutoSignalPlacement();
00753 break;
00754
00755 case DDSP_DEMOLISH_AREA:
00756 GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
00757 break;
00758
00759 case DDSP_CONVERT_RAIL:
00760 DoCommandP(end_tile, start_tile, _cur_railtype, CMD_CONVERT_RAIL | CMD_MSG(STR_ERROR_CAN_T_CONVERT_RAIL), CcPlaySound10);
00761 break;
00762
00763 case DDSP_REMOVE_STATION:
00764 case DDSP_BUILD_STATION:
00765 if (this->IsWidgetLowered(RTW_BUILD_STATION)) {
00766
00767 if (_remove_button_clicked) {
00768 DoCommandP(end_tile, start_tile, _ctrl_pressed ? 0 : 1, CMD_REMOVE_FROM_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_REMOVE_PART_OF_STATION), CcPlaySound1E);
00769 } else {
00770 HandleStationPlacement(start_tile, end_tile);
00771 }
00772 } else {
00773
00774 if (_remove_button_clicked) {
00775 DoCommandP(end_tile, start_tile, _ctrl_pressed ? 0 : 1, CMD_REMOVE_FROM_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT), CcPlaySound1E);
00776 } else {
00777 TileArea ta(start_tile, end_tile);
00778 uint32 p1 = _cur_railtype | (select_method == VPM_FIX_X ? AXIS_X : AXIS_Y) << 4 | ta.w << 8 | ta.h << 16 | _ctrl_pressed << 24;
00779 uint32 p2 = STAT_CLASS_WAYP | _cur_waypoint_type << 8 | INVALID_STATION << 16;
00780
00781 CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT), CcPlaySound1E, "" };
00782 ShowSelectWaypointIfNeeded(cmdcont, ta);
00783 }
00784 }
00785 break;
00786 }
00787 }
00788 }
00789
00790 virtual void OnPlaceObjectAbort()
00791 {
00792 this->RaiseButtons();
00793 this->DisableWidget(RTW_REMOVE);
00794 this->SetWidgetDirty(RTW_REMOVE);
00795
00796 DeleteWindowById(WC_BUILD_SIGNAL, TRANSPORT_RAIL);
00797 DeleteWindowById(WC_BUILD_STATION, TRANSPORT_RAIL);
00798 DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_RAIL);
00799 DeleteWindowById(WC_SELECT_STATION, 0);
00800 DeleteWindowByClass(WC_BUILD_BRIDGE);
00801 }
00802
00803 virtual void OnPlacePresize(Point pt, TileIndex tile)
00804 {
00805 DoCommand(tile, _cur_railtype, 0, DC_AUTO, CMD_BUILD_TUNNEL);
00806 VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
00807 }
00808
00809 virtual EventState OnCTRLStateChange()
00810 {
00811
00812 if (!this->IsWidgetLowered(RTW_BUILD_STATION) && !this->IsWidgetLowered(RTW_BUILD_WAYPOINT) && RailToolbar_CtrlChanged(this)) return ES_HANDLED;
00813 return ES_NOT_HANDLED;
00814 }
00815 };
00816
00817 static const NWidgetPart _nested_build_rail_widgets[] = {
00818 NWidget(NWID_HORIZONTAL),
00819 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
00820 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, RTW_CAPTION), SetDataTip(STR_RAIL_TOOLBAR_RAILROAD_CONSTRUCTION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00821 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
00822 EndContainer(),
00823 NWidget(NWID_HORIZONTAL),
00824 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_NS),
00825 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_RAIL_NS, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
00826 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_X),
00827 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_RAIL_NE, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
00828 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_EW),
00829 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_RAIL_EW, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
00830 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_Y),
00831 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_RAIL_NW, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
00832 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_AUTORAIL),
00833 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTORAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL),
00834
00835 NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetMinimalSize(4, 22), SetDataTip(0x0, STR_NULL), EndContainer(),
00836
00837 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_DEMOLISH),
00838 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
00839 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_DEPOT),
00840 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DEPOT_RAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING),
00841 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_WAYPOINT),
00842 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_WAYPOINT, STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT),
00843 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_STATION),
00844 SetFill(0, 1), SetMinimalSize(42, 22), SetDataTip(SPR_IMG_RAIL_STATION, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION),
00845 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_SIGNALS),
00846 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_RAIL_SIGNALS, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS),
00847 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_BRIDGE),
00848 SetFill(0, 1), SetMinimalSize(42, 22), SetDataTip(SPR_IMG_BRIDGE, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE),
00849 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_TUNNEL),
00850 SetFill(0, 1), SetMinimalSize(20, 22), SetDataTip(SPR_IMG_TUNNEL_RAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL),
00851 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_REMOVE),
00852 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE, STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR),
00853 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_CONVERT_RAIL),
00854 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_CONVERT_RAIL, STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL),
00855 EndContainer(),
00856 };
00857
00858 static const WindowDesc _build_rail_desc(
00859 WDP_ALIGN_TOOLBAR, 0, 0,
00860 WC_BUILD_TOOLBAR, WC_NONE,
00861 WDF_CONSTRUCTION,
00862 _nested_build_rail_widgets, lengthof(_nested_build_rail_widgets)
00863 );
00864
00865
00877 void ShowBuildRailToolbar(RailType railtype, int button)
00878 {
00879 if (!Company::IsValidID(_local_company)) return;
00880 if (!ValParamRailtype(railtype)) return;
00881
00882 BuildRailToolbarWindow *w = (BuildRailToolbarWindow *)FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_RAIL);
00883
00884
00885 if (button < 0 || w == NULL) {
00886 DeleteWindowByClass(WC_BUILD_TOOLBAR);
00887 _cur_railtype = railtype;
00888 w = new BuildRailToolbarWindow(&_build_rail_desc, TRANSPORT_RAIL, railtype);
00889 }
00890
00891 _remove_button_clicked = false;
00892 if (w != NULL && button >= 0) {
00893 _rail_build_button_data[button].click_proc(w);
00894 w->UpdateRemoveWidgetStatus(button + RTW_BUILD_NS);
00895 }
00896 }
00897
00898
00899
00900
00901 static void HandleStationPlacement(TileIndex start, TileIndex end)
00902 {
00903 TileArea ta(start, end);
00904 uint numtracks = ta.w;
00905 uint platlength = ta.h;
00906
00907 if (_railstation.orientation == AXIS_X) Swap(numtracks, platlength);
00908
00909 uint32 p1 = _cur_railtype | _railstation.orientation << 4 | numtracks << 8 | platlength << 16 | _ctrl_pressed << 24;
00910 uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16;
00911
00912 CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" };
00913 ShowSelectStationIfNeeded(cmdcont, ta);
00914 }
00915
00917 enum BuildRailStationWidgets {
00918 BRSW_BACKGROUND,
00919
00920 BRSW_PLATFORM_DIR_X,
00921 BRSW_PLATFORM_DIR_Y,
00922
00923 BRSW_PLATFORM_NUM_1,
00924 BRSW_PLATFORM_NUM_2,
00925 BRSW_PLATFORM_NUM_3,
00926 BRSW_PLATFORM_NUM_4,
00927 BRSW_PLATFORM_NUM_5,
00928 BRSW_PLATFORM_NUM_6,
00929 BRSW_PLATFORM_NUM_7,
00930
00931 BRSW_PLATFORM_LEN_1,
00932 BRSW_PLATFORM_LEN_2,
00933 BRSW_PLATFORM_LEN_3,
00934 BRSW_PLATFORM_LEN_4,
00935 BRSW_PLATFORM_LEN_5,
00936 BRSW_PLATFORM_LEN_6,
00937 BRSW_PLATFORM_LEN_7,
00938
00939 BRSW_PLATFORM_DRAG_N_DROP,
00940
00941 BRSW_HIGHLIGHT_OFF,
00942 BRSW_HIGHLIGHT_ON,
00943
00944 BRSW_NEWST_DROPDOWN,
00945 BRSW_NEWST_LIST,
00946 BRSW_NEWST_SCROLL,
00947
00948 BRSW_PLATFORM_NUM_BEGIN = BRSW_PLATFORM_NUM_1 - 1,
00949 BRSW_PLATFORM_LEN_BEGIN = BRSW_PLATFORM_LEN_1 - 1,
00950 };
00951
00952 struct BuildRailStationWindow : public PickerWindowBase {
00953 private:
00954 uint line_height;
00955
00961 void CheckSelectedSize(const StationSpec *statspec)
00962 {
00963 if (statspec == NULL || _settings_client.gui.station_dragdrop) return;
00964
00965
00966 if (HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
00967 this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
00968 _settings_client.gui.station_numtracks = 1;
00969 while (HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
00970 _settings_client.gui.station_numtracks++;
00971 }
00972 this->LowerWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
00973 }
00974
00975 if (HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
00976 this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
00977 _settings_client.gui.station_platlength = 1;
00978 while (HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
00979 _settings_client.gui.station_platlength++;
00980 }
00981 this->LowerWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
00982 }
00983 }
00984
00986 static DropDownList *BuildStationClassDropDown()
00987 {
00988 DropDownList *list = new DropDownList();
00989
00990 for (uint i = 0; i < GetNumStationClasses(); i++) {
00991 if (i == STAT_CLASS_WAYP) continue;
00992 list->push_back(new DropDownListStringItem(GetStationClassName((StationClassID)i), i, false));
00993 }
00994
00995 return list;
00996 }
00997
00998 public:
00999 BuildRailStationWindow(const WindowDesc *desc, Window *parent, bool newstation) : PickerWindowBase(parent)
01000 {
01001 this->InitNested(desc, TRANSPORT_RAIL);
01002
01003 this->LowerWidget(_railstation.orientation + BRSW_PLATFORM_DIR_X);
01004 if (_settings_client.gui.station_dragdrop) {
01005 this->LowerWidget(BRSW_PLATFORM_DRAG_N_DROP);
01006 } else {
01007 this->LowerWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
01008 this->LowerWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
01009 }
01010 this->SetWidgetLoweredState(BRSW_HIGHLIGHT_OFF, !_settings_client.gui.station_show_coverage);
01011 this->SetWidgetLoweredState(BRSW_HIGHLIGHT_ON, _settings_client.gui.station_show_coverage);
01012
01013 _railstation.newstations = newstation;
01014
01015 if (newstation) {
01016 _railstation.station_count = GetNumCustomStations(_railstation.station_class);
01017
01018 this->vscroll.SetCount(_railstation.station_count);
01019 this->vscroll.SetCapacity(GB(this->GetWidget<NWidgetCore>(BRSW_NEWST_LIST)->widget_data, MAT_ROW_START, MAT_ROW_BITS));
01020 this->vscroll.SetPosition(Clamp(_railstation.station_type - 2, 0, max(this->vscroll.GetCount() - this->vscroll.GetCapacity(), 0)));
01021 } else {
01022
01023
01024 _railstation.station_class = STAT_CLASS_DFLT;
01025 _railstation.station_type = 0;
01026 }
01027 }
01028
01029 virtual ~BuildRailStationWindow()
01030 {
01031 DeleteWindowById(WC_SELECT_STATION, 0);
01032 }
01033
01034 virtual void OnPaint()
01035 {
01036 bool newstations = _railstation.newstations;
01037 const StationSpec *statspec = newstations ? GetCustomStationSpec(_railstation.station_class, _railstation.station_type) : NULL;
01038
01039 if (_settings_client.gui.station_dragdrop) {
01040 SetTileSelectSize(1, 1);
01041 } else {
01042 int x = _settings_client.gui.station_numtracks;
01043 int y = _settings_client.gui.station_platlength;
01044 if (_railstation.orientation == AXIS_X) Swap(x, y);
01045 if (!_remove_button_clicked)
01046 SetTileSelectSize(x, y);
01047 }
01048
01049 int rad = (_settings_game.station.modified_catchment) ? CA_TRAIN : CA_UNMODIFIED;
01050
01051 if (_settings_client.gui.station_show_coverage)
01052 SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
01053
01054 for (uint bits = 0; bits < 7; bits++) {
01055 bool disable = bits >= _settings_game.station.station_spread;
01056 if (statspec == NULL) {
01057 this->SetWidgetDisabledState(bits + BRSW_PLATFORM_NUM_1, disable);
01058 this->SetWidgetDisabledState(bits + BRSW_PLATFORM_LEN_1, disable);
01059 } else {
01060 this->SetWidgetDisabledState(bits + BRSW_PLATFORM_NUM_1, HasBit(statspec->disallowed_platforms, bits) || disable);
01061 this->SetWidgetDisabledState(bits + BRSW_PLATFORM_LEN_1, HasBit(statspec->disallowed_lengths, bits) || disable);
01062 }
01063 }
01064
01065 this->DrawWidgets();
01066
01067
01068 int top = this->GetWidget<NWidgetBase>(BRSW_HIGHLIGHT_ON)->pos_y + this->GetWidget<NWidgetBase>(BRSW_HIGHLIGHT_ON)->current_y + WD_PAR_VSEP_NORMAL;
01069 NWidgetBase *back_nwi = this->GetWidget<NWidgetBase>(BRSW_BACKGROUND);
01070 int right = back_nwi->pos_x + back_nwi->current_x;
01071 int bottom = back_nwi->pos_y + back_nwi->current_y;
01072 top = DrawStationCoverageAreaText(back_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, SCT_ALL, rad, false) + WD_PAR_VSEP_NORMAL;
01073 top = DrawStationCoverageAreaText(back_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, SCT_ALL, rad, true) + WD_PAR_VSEP_NORMAL;
01074
01075 if (top > bottom || (top < bottom && back_nwi->current_y > back_nwi->smallest_y)) {
01076 ResizeWindow(this, 0, top - bottom);
01077 }
01078 }
01079
01080 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
01081 {
01082 switch (widget) {
01083 case BRSW_NEWST_DROPDOWN: {
01084 Dimension d = {0, 0};
01085 for (uint i = 0; i < GetNumStationClasses(); i++) {
01086 if (i == STAT_CLASS_WAYP) continue;
01087 SetDParam(0, GetStationClassName((StationClassID)i));
01088 d = maxdim(d, GetStringBoundingBox(STR_BLACK_STRING));
01089 }
01090 d.width += padding.width;
01091 d.height += padding.height;
01092 *size = maxdim(*size, d);
01093 break;
01094 }
01095 case BRSW_NEWST_LIST: {
01096 Dimension d = GetStringBoundingBox(STR_STATION_CLASS_DFLT);
01097 for (StationClassID statclass = STAT_CLASS_BEGIN; statclass < (StationClassID)GetNumStationClasses(); statclass++) {
01098 if (statclass == STAT_CLASS_WAYP) continue;
01099 for (uint16 j = 0; j < GetNumCustomStations(statclass); j++) {
01100 const StationSpec *statspec = GetCustomStationSpec(statclass, j);
01101 if (statspec != NULL && statspec->name != 0) d = maxdim(d, GetStringBoundingBox(statspec->name));
01102 }
01103 }
01104 size->width = max(size->width, d.width + padding.width);
01105
01106 this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
01107 size->height = GB(this->GetWidget<NWidgetCore>(widget)->widget_data, MAT_ROW_START, MAT_ROW_BITS) * this->line_height;
01108 break;
01109 }
01110 }
01111 }
01112
01113 virtual void DrawWidget(const Rect &r, int widget) const
01114 {
01115 DrawPixelInfo tmp_dpi;
01116
01117 switch (widget) {
01118 case BRSW_PLATFORM_DIR_X:
01119
01120 if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left + 1, r.bottom - r.top + 1)) {
01121 DrawPixelInfo *old_dpi = _cur_dpi;
01122 _cur_dpi = &tmp_dpi;
01123 if (!DrawStationTile(32, 16, _cur_railtype, AXIS_X, _railstation.station_class, _railstation.station_type)) {
01124 StationPickerDrawSprite(32, 16, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2);
01125 }
01126 _cur_dpi = old_dpi;
01127 }
01128 break;
01129
01130 case BRSW_PLATFORM_DIR_Y:
01131
01132 if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left + 1, r.bottom - r.top + 1)) {
01133 DrawPixelInfo *old_dpi = _cur_dpi;
01134 _cur_dpi = &tmp_dpi;
01135 if (!DrawStationTile(32, 16, _cur_railtype, AXIS_Y, _railstation.station_class, _railstation.station_type)) {
01136 StationPickerDrawSprite(32, 16, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 3);
01137 }
01138 _cur_dpi = old_dpi;
01139 }
01140 break;
01141
01142 case BRSW_NEWST_LIST: {
01143 uint y = r.top;
01144 for (uint16 i = this->vscroll.GetPosition(); i < _railstation.station_count && this->vscroll.IsVisible(i); i++) {
01145 const StationSpec *statspec = GetCustomStationSpec(_railstation.station_class, i);
01146
01147 StringID str = STR_STATION_CLASS_DFLT;
01148 if (statspec != NULL && statspec->name != 0) {
01149 if (HasBit(statspec->callback_mask, CBM_STATION_AVAIL) && GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) {
01150 GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->line_height - 2, 0, FILLRECT_CHECKER);
01151 }
01152 str = statspec->name;
01153 }
01154 DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, str, i == _railstation.station_type ? TC_WHITE : TC_BLACK);
01155
01156 y += this->line_height;
01157 }
01158 break;
01159 }
01160 }
01161 }
01162
01163 virtual void SetStringParameters(int widget) const
01164 {
01165 if (widget == BRSW_NEWST_DROPDOWN) SetDParam(0, GetStationClassName(_railstation.station_class));
01166 }
01167
01168 virtual void OnClick(Point pt, int widget)
01169 {
01170 switch (widget) {
01171 case BRSW_PLATFORM_DIR_X:
01172 case BRSW_PLATFORM_DIR_Y:
01173 this->RaiseWidget(_railstation.orientation + BRSW_PLATFORM_DIR_X);
01174 _railstation.orientation = (Axis)(widget - BRSW_PLATFORM_DIR_X);
01175 this->LowerWidget(_railstation.orientation + BRSW_PLATFORM_DIR_X);
01176 SndPlayFx(SND_15_BEEP);
01177 this->SetDirty();
01178 DeleteWindowById(WC_SELECT_STATION, 0);
01179 break;
01180
01181 case BRSW_PLATFORM_NUM_1:
01182 case BRSW_PLATFORM_NUM_2:
01183 case BRSW_PLATFORM_NUM_3:
01184 case BRSW_PLATFORM_NUM_4:
01185 case BRSW_PLATFORM_NUM_5:
01186 case BRSW_PLATFORM_NUM_6:
01187 case BRSW_PLATFORM_NUM_7: {
01188 this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
01189 this->RaiseWidget(BRSW_PLATFORM_DRAG_N_DROP);
01190
01191 _settings_client.gui.station_numtracks = widget - BRSW_PLATFORM_NUM_BEGIN;
01192 _settings_client.gui.station_dragdrop = false;
01193
01194 _settings_client.gui.station_dragdrop = false;
01195
01196 const StationSpec *statspec = _railstation.newstations ? GetCustomStationSpec(_railstation.station_class, _railstation.station_type) : NULL;
01197 if (statspec != NULL && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
01198
01199 for (uint i = 0; i < 7; i++) {
01200 if (!HasBit(statspec->disallowed_lengths, i)) {
01201 this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
01202 _settings_client.gui.station_platlength = i + 1;
01203 break;
01204 }
01205 }
01206 }
01207
01208 this->LowerWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
01209 this->LowerWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
01210 SndPlayFx(SND_15_BEEP);
01211 this->SetDirty();
01212 DeleteWindowById(WC_SELECT_STATION, 0);
01213 break;
01214 }
01215
01216 case BRSW_PLATFORM_LEN_1:
01217 case BRSW_PLATFORM_LEN_2:
01218 case BRSW_PLATFORM_LEN_3:
01219 case BRSW_PLATFORM_LEN_4:
01220 case BRSW_PLATFORM_LEN_5:
01221 case BRSW_PLATFORM_LEN_6:
01222 case BRSW_PLATFORM_LEN_7: {
01223 this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
01224 this->RaiseWidget(BRSW_PLATFORM_DRAG_N_DROP);
01225
01226 _settings_client.gui.station_platlength = widget - BRSW_PLATFORM_LEN_BEGIN;
01227 _settings_client.gui.station_dragdrop = false;
01228
01229 _settings_client.gui.station_dragdrop = false;
01230
01231 const StationSpec *statspec = _railstation.newstations ? GetCustomStationSpec(_railstation.station_class, _railstation.station_type) : NULL;
01232 if (statspec != NULL && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
01233
01234 for (uint i = 0; i < 7; i++) {
01235 if (!HasBit(statspec->disallowed_platforms, i)) {
01236 this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
01237 _settings_client.gui.station_numtracks = i + 1;
01238 break;
01239 }
01240 }
01241 }
01242
01243 this->LowerWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
01244 this->LowerWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
01245 SndPlayFx(SND_15_BEEP);
01246 this->SetDirty();
01247 DeleteWindowById(WC_SELECT_STATION, 0);
01248 break;
01249 }
01250
01251 case BRSW_PLATFORM_DRAG_N_DROP: {
01252 _settings_client.gui.station_dragdrop ^= true;
01253
01254 this->ToggleWidgetLoweredState(BRSW_PLATFORM_DRAG_N_DROP);
01255
01256
01257 const StationSpec *statspec = _railstation.newstations ? GetCustomStationSpec(_railstation.station_class, _railstation.station_type) : NULL;
01258 if (statspec != NULL && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
01259 for (uint i = 0; i < 7; i++) {
01260 if (!HasBit(statspec->disallowed_lengths, i)) {
01261 this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
01262 _settings_client.gui.station_platlength = i + 1;
01263 break;
01264 }
01265 }
01266 }
01267 if (statspec != NULL && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
01268 for (uint i = 0; i < 7; i++) {
01269 if (!HasBit(statspec->disallowed_platforms, i)) {
01270 this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
01271 _settings_client.gui.station_numtracks = i + 1;
01272 break;
01273 }
01274 }
01275 }
01276
01277 this->SetWidgetLoweredState(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN, !_settings_client.gui.station_dragdrop);
01278 this->SetWidgetLoweredState(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN, !_settings_client.gui.station_dragdrop);
01279 SndPlayFx(SND_15_BEEP);
01280 this->SetDirty();
01281 DeleteWindowById(WC_SELECT_STATION, 0);
01282 } break;
01283
01284 case BRSW_HIGHLIGHT_OFF:
01285 case BRSW_HIGHLIGHT_ON:
01286 _settings_client.gui.station_show_coverage = (widget != BRSW_HIGHLIGHT_OFF);
01287
01288 this->SetWidgetLoweredState(BRSW_HIGHLIGHT_OFF, !_settings_client.gui.station_show_coverage);
01289 this->SetWidgetLoweredState(BRSW_HIGHLIGHT_ON, _settings_client.gui.station_show_coverage);
01290 SndPlayFx(SND_15_BEEP);
01291 this->SetDirty();
01292 break;
01293
01294 case BRSW_NEWST_DROPDOWN:
01295 ShowDropDownList(this, BuildStationClassDropDown(), _railstation.station_class, BRSW_NEWST_DROPDOWN);
01296 break;
01297
01298 case BRSW_NEWST_LIST: {
01299 const StationSpec *statspec;
01300 int y = (pt.y - this->GetWidget<NWidgetBase>(BRSW_NEWST_LIST)->pos_y) / this->line_height;
01301
01302 if (y >= this->vscroll.GetCapacity()) return;
01303 y += this->vscroll.GetPosition();
01304 if (y >= _railstation.station_count) return;
01305
01306
01307 statspec = GetCustomStationSpec(_railstation.station_class, y);
01308 if (statspec != NULL &&
01309 HasBit(statspec->callback_mask, CBM_STATION_AVAIL) &&
01310 GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) return;
01311
01312 _railstation.station_type = y;
01313
01314 this->CheckSelectedSize(statspec);
01315
01316 SndPlayFx(SND_15_BEEP);
01317 this->SetDirty();
01318 DeleteWindowById(WC_SELECT_STATION, 0);
01319 break;
01320 }
01321 }
01322 }
01323
01324 virtual void OnDropdownSelect(int widget, int index)
01325 {
01326 if (_railstation.station_class != index) {
01327 _railstation.station_class = (StationClassID)index;
01328 _railstation.station_type = 0;
01329 _railstation.station_count = GetNumCustomStations(_railstation.station_class);
01330
01331 this->CheckSelectedSize(GetCustomStationSpec(_railstation.station_class, _railstation.station_type));
01332
01333 this->vscroll.SetCount(_railstation.station_count);
01334 this->vscroll.SetPosition(_railstation.station_type);
01335 }
01336
01337 SndPlayFx(SND_15_BEEP);
01338 this->SetDirty();
01339 DeleteWindowById(WC_SELECT_STATION, 0);
01340 }
01341
01342 virtual void OnTick()
01343 {
01344 CheckRedrawStationCoverage(this);
01345 }
01346 };
01347
01348 static const NWidgetPart _nested_station_builder_widgets[] = {
01349 NWidget(NWID_HORIZONTAL),
01350 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
01351 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_RAIL_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
01352 EndContainer(),
01353 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BRSW_BACKGROUND),
01354 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_ORIENTATION, STR_NULL), SetPadding(1, 2, 0, 2),
01355 NWidget(NWID_HORIZONTAL),
01356 NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0),
01357 NWidget(WWT_PANEL, COLOUR_GREY, BRSW_PLATFORM_DIR_X), SetMinimalSize(66, 48), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(),
01358 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01359 NWidget(WWT_PANEL, COLOUR_GREY, BRSW_PLATFORM_DIR_Y), SetMinimalSize(66, 48), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(),
01360 NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0),
01361 EndContainer(),
01362 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_NUMBER_OF_TRACKS, STR_NULL), SetPadding(2, 2, 0, 2),
01363 NWidget(NWID_HORIZONTAL),
01364 NWidget(NWID_SPACER), SetFill(1, 0),
01365 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_1), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_1, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01366 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_2), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_2, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01367 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_3), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_3, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01368 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_4), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_4, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01369 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_5), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_5, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01370 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_6), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_6, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01371 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_7), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_7, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01372 NWidget(NWID_SPACER), SetFill(1, 0),
01373 EndContainer(),
01374 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_PLATFORM_LENGTH, STR_NULL), SetPadding(2, 2, 0, 2),
01375 NWidget(NWID_HORIZONTAL),
01376 NWidget(NWID_SPACER), SetFill(1, 0),
01377 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_1), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_1, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01378 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_2), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_2, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01379 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_3), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_3, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01380 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_4), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_4, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01381 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_5), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_5, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01382 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_6), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_6, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01383 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_7), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_7, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01384 NWidget(NWID_SPACER), SetFill(1, 0),
01385 EndContainer(),
01386 NWidget(NWID_SPACER), SetMinimalSize(0, 2),
01387 NWidget(NWID_HORIZONTAL),
01388 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01389 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_DRAG_N_DROP), SetMinimalSize(75, 12), SetDataTip(STR_STATION_BUILD_DRAG_DROP, STR_STATION_BUILD_DRAG_DROP_TOOLTIP),
01390 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01391 EndContainer(),
01392 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetPadding(3, 2, 0, 2),
01393 NWidget(NWID_HORIZONTAL),
01394 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01395 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_HIGHLIGHT_OFF), SetMinimalSize(60, 12),
01396 SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
01397 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_HIGHLIGHT_ON), SetMinimalSize(60, 12),
01398 SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
01399 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01400 EndContainer(),
01401 NWidget(NWID_SPACER), SetMinimalSize(0, 20), SetResize(0, 1),
01402 EndContainer(),
01403 };
01404
01405 static const NWidgetPart _nested_newstation_builder_widgets[] = {
01406 NWidget(NWID_HORIZONTAL),
01407 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
01408 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_RAIL_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
01409 EndContainer(),
01410 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BRSW_BACKGROUND),
01411
01412 NWidget(WWT_DROPDOWN, COLOUR_GREY, BRSW_NEWST_DROPDOWN), SetMinimalSize(134, 12), SetFill(1, 0), SetPadding(3, 7, 3, 7), SetDataTip(STR_BLACK_STRING, STR_STATION_BUILD_STATION_CLASS_TOOLTIP),
01413 NWidget(NWID_HORIZONTAL), SetPIP(7, 0, 7),
01414 NWidget(WWT_MATRIX, COLOUR_GREY, BRSW_NEWST_LIST), SetMinimalSize(122, 71), SetFill(1, 0), SetDataTip(0x501, STR_STATION_BUILD_STATION_TYPE_TOOLTIP),
01415 NWidget(WWT_SCROLLBAR, COLOUR_GREY, BRSW_NEWST_SCROLL),
01416 EndContainer(),
01417 NWidget(NWID_SPACER), SetMinimalSize(0, 1),
01418
01419 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_ORIENTATION, STR_NULL), SetPadding(1, 2, 0, 2),
01420 NWidget(NWID_HORIZONTAL),
01421 NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0),
01422 NWidget(WWT_PANEL, COLOUR_GREY, BRSW_PLATFORM_DIR_X), SetMinimalSize(66, 48), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(),
01423 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01424 NWidget(WWT_PANEL, COLOUR_GREY, BRSW_PLATFORM_DIR_Y), SetMinimalSize(66, 48), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(),
01425 NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0),
01426 EndContainer(),
01427 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_NUMBER_OF_TRACKS, STR_NULL), SetPadding(2, 2, 0, 2),
01428 NWidget(NWID_HORIZONTAL),
01429 NWidget(NWID_SPACER), SetFill(1, 0),
01430 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_1), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_1, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01431 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_2), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_2, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01432 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_3), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_3, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01433 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_4), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_4, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01434 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_5), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_5, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01435 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_6), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_6, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01436 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_7), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_7, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01437 NWidget(NWID_SPACER), SetFill(1, 0),
01438 EndContainer(),
01439 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_PLATFORM_LENGTH, STR_NULL), SetPadding(2, 2, 0, 2),
01440 NWidget(NWID_HORIZONTAL),
01441 NWidget(NWID_SPACER), SetFill(1, 0),
01442 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_1), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_1, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01443 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_2), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_2, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01444 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_3), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_3, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01445 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_4), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_4, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01446 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_5), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_5, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01447 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_6), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_6, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01448 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_7), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_7, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01449 NWidget(NWID_SPACER), SetFill(1, 0),
01450 EndContainer(),
01451 NWidget(NWID_SPACER), SetMinimalSize(0, 2),
01452 NWidget(NWID_HORIZONTAL),
01453 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01454 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_DRAG_N_DROP), SetMinimalSize(75, 12), SetDataTip(STR_STATION_BUILD_DRAG_DROP, STR_STATION_BUILD_DRAG_DROP_TOOLTIP),
01455 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01456 EndContainer(),
01457 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetPadding(3, 2, 0, 2),
01458 NWidget(NWID_HORIZONTAL),
01459 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01460 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_HIGHLIGHT_OFF), SetMinimalSize(60, 12),
01461 SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
01462 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_HIGHLIGHT_ON), SetMinimalSize(60, 12),
01463 SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
01464 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01465 EndContainer(),
01466 NWidget(NWID_SPACER), SetMinimalSize(0, 20), SetResize(0, 1),
01467 EndContainer(),
01468 };
01469
01471 static const WindowDesc _station_builder_desc(
01472 WDP_AUTO, 0, 0,
01473 WC_BUILD_STATION, WC_BUILD_TOOLBAR,
01474 WDF_CONSTRUCTION,
01475 _nested_station_builder_widgets, lengthof(_nested_station_builder_widgets)
01476 );
01477
01479 static const WindowDesc _newstation_builder_desc(
01480 WDP_AUTO, 0, 0,
01481 WC_BUILD_STATION, WC_BUILD_TOOLBAR,
01482 WDF_CONSTRUCTION,
01483 _nested_newstation_builder_widgets, lengthof(_nested_newstation_builder_widgets)
01484 );
01485
01487 static void ShowStationBuilder(Window *parent)
01488 {
01489 if (GetNumStationClasses() <= 2 && GetNumCustomStations(STAT_CLASS_DFLT) == 1) {
01490 new BuildRailStationWindow(&_station_builder_desc, parent, false);
01491 } else {
01492 new BuildRailStationWindow(&_newstation_builder_desc, parent, true);
01493 }
01494 }
01495
01497 enum BuildSignalWidgets {
01498 BSW_SEMAPHORE_NORM,
01499 BSW_SEMAPHORE_ENTRY,
01500 BSW_SEMAPHORE_EXIT,
01501 BSW_SEMAPHORE_COMBO,
01502 BSW_SEMAPHORE_PBS,
01503 BSW_SEMAPHORE_PBS_OWAY,
01504 BSW_ELECTRIC_NORM,
01505 BSW_ELECTRIC_ENTRY,
01506 BSW_ELECTRIC_EXIT,
01507 BSW_ELECTRIC_COMBO,
01508 BSW_ELECTRIC_PBS,
01509 BSW_ELECTRIC_PBS_OWAY,
01510 BSW_CONVERT,
01511 BSW_DRAG_SIGNALS_DENSITY,
01512 BSW_DRAG_SIGNALS_DENSITY_LABEL,
01513 BSW_DRAG_SIGNALS_DENSITY_DECREASE,
01514 BSW_DRAG_SIGNALS_DENSITY_INCREASE,
01515 };
01516
01517 struct BuildSignalWindow : public PickerWindowBase {
01518 private:
01526 void DrawSignalSprite(byte widget_index, SpriteID image) const
01527 {
01528
01529 image += this->IsWidgetLowered(widget_index);
01530
01531
01532 const Sprite *sprite = GetSprite(image, ST_NORMAL);
01533
01534
01535
01536
01537
01538 int sprite_center_x_offset = sprite->x_offs + sprite->width / 2;
01539 int sprite_bottom_y_offset = sprite->height + sprite->y_offs;
01540
01541
01542
01543 const NWidgetBase *widget = this->GetWidget<NWidgetBase>(widget_index);
01544 int widget_center_x = widget->pos_x + widget->current_x / 2;
01545 int widget_bottom_y = widget->pos_y + widget->current_y - 2;
01546
01547
01548 DrawSprite(image, PAL_NONE,
01549 widget_center_x - sprite_center_x_offset + this->IsWidgetLowered(widget_index),
01550 widget_bottom_y - sprite_bottom_y_offset + this->IsWidgetLowered(widget_index));
01551 }
01552
01553 public:
01554 BuildSignalWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(parent)
01555 {
01556 this->InitNested(desc, TRANSPORT_RAIL);
01557 this->OnInvalidateData();
01558 };
01559
01560 virtual void SetStringParameters(int widget) const
01561 {
01562 switch (widget) {
01563 case BSW_DRAG_SIGNALS_DENSITY_LABEL:
01564 SetDParam(0, _settings_client.gui.drag_signals_density);
01565 break;
01566 }
01567 }
01568
01569 virtual void OnPaint()
01570 {
01571 this->DrawWidgets();
01572 }
01573
01574 virtual void DrawWidget(const Rect &r, int widget) const
01575 {
01576 if (IsInsideMM(widget, BSW_SEMAPHORE_NORM, BSW_ELECTRIC_PBS_OWAY + 1)) {
01577
01578 const SpriteID _signal_lookup[] = {
01579 SPR_IMG_SIGNAL_SEMAPHORE_NORM, SPR_IMG_SIGNAL_SEMAPHORE_ENTRY, SPR_IMG_SIGNAL_SEMAPHORE_EXIT,
01580 SPR_IMG_SIGNAL_SEMAPHORE_COMBO, SPR_IMG_SIGNAL_SEMAPHORE_PBS, SPR_IMG_SIGNAL_SEMAPHORE_PBS_OWAY,
01581
01582 SPR_IMG_SIGNAL_ELECTRIC_NORM, SPR_IMG_SIGNAL_ELECTRIC_ENTRY, SPR_IMG_SIGNAL_ELECTRIC_EXIT,
01583 SPR_IMG_SIGNAL_ELECTRIC_COMBO, SPR_IMG_SIGNAL_ELECTRIC_PBS, SPR_IMG_SIGNAL_ELECTRIC_PBS_OWAY
01584 };
01585
01586 this->DrawSignalSprite(widget, _signal_lookup[widget - BSW_SEMAPHORE_NORM]);
01587 }
01588 }
01589
01590 virtual void OnClick(Point pt, int widget)
01591 {
01592 switch (widget) {
01593 case BSW_SEMAPHORE_NORM:
01594 case BSW_SEMAPHORE_ENTRY:
01595 case BSW_SEMAPHORE_EXIT:
01596 case BSW_SEMAPHORE_COMBO:
01597 case BSW_SEMAPHORE_PBS:
01598 case BSW_SEMAPHORE_PBS_OWAY:
01599 case BSW_ELECTRIC_NORM:
01600 case BSW_ELECTRIC_ENTRY:
01601 case BSW_ELECTRIC_EXIT:
01602 case BSW_ELECTRIC_COMBO:
01603 case BSW_ELECTRIC_PBS:
01604 case BSW_ELECTRIC_PBS_OWAY:
01605 this->RaiseWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type);
01606
01607 _cur_signal_type = (SignalType)((uint)((widget - BSW_SEMAPHORE_NORM) % (SIGTYPE_LAST + 1)));
01608 _cur_signal_variant = widget >= BSW_ELECTRIC_NORM ? SIG_ELECTRIC : SIG_SEMAPHORE;
01609 break;
01610
01611 case BSW_CONVERT:
01612 _convert_signal_button = !_convert_signal_button;
01613 break;
01614
01615 case BSW_DRAG_SIGNALS_DENSITY_DECREASE:
01616 if (_settings_client.gui.drag_signals_density > 1) {
01617 _settings_client.gui.drag_signals_density--;
01618 SetWindowDirty(WC_GAME_OPTIONS, 0);
01619 }
01620 break;
01621
01622 case BSW_DRAG_SIGNALS_DENSITY_INCREASE:
01623 if (_settings_client.gui.drag_signals_density < 20) {
01624 _settings_client.gui.drag_signals_density++;
01625 SetWindowDirty(WC_GAME_OPTIONS, 0);
01626 }
01627 break;
01628
01629 default: break;
01630 }
01631
01632 this->InvalidateData();
01633 }
01634
01635 virtual void OnInvalidateData(int data = 0)
01636 {
01637 this->LowerWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type);
01638
01639 this->SetWidgetLoweredState(BSW_CONVERT, _convert_signal_button);
01640
01641 this->SetWidgetDisabledState(BSW_DRAG_SIGNALS_DENSITY_DECREASE, _settings_client.gui.drag_signals_density == 1);
01642 this->SetWidgetDisabledState(BSW_DRAG_SIGNALS_DENSITY_INCREASE, _settings_client.gui.drag_signals_density == 20);
01643 }
01644 };
01645
01647 static const NWidgetPart _nested_signal_builder_widgets[] = {
01648 NWidget(NWID_HORIZONTAL),
01649 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
01650 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_BUILD_SIGNAL_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
01651 EndContainer(),
01652 NWidget(NWID_VERTICAL, NC_EQUALSIZE),
01653 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
01654 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_NORM), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP), EndContainer(), SetFill(1, 1),
01655 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_ENTRY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP), EndContainer(), SetFill(1, 1),
01656 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_EXIT), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP), EndContainer(), SetFill(1, 1),
01657 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_COMBO), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP), EndContainer(), SetFill(1, 1),
01658 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_PBS), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP), EndContainer(), SetFill(1, 1),
01659 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_PBS_OWAY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP), EndContainer(), SetFill(1, 1),
01660 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, BSW_CONVERT), SetDataTip(SPR_IMG_SIGNAL_CONVERT, STR_BUILD_SIGNAL_CONVERT_TOOLTIP), SetFill(1, 1),
01661 EndContainer(),
01662 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
01663 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_NORM), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP), EndContainer(), SetFill(1, 1),
01664 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_ENTRY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TOOLTIP), EndContainer(), SetFill(1, 1),
01665 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_EXIT), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP), EndContainer(), SetFill(1, 1),
01666 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_COMBO), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP), EndContainer(), SetFill(1, 1),
01667 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_PBS), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP), EndContainer(), SetFill(1, 1),
01668 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_PBS_OWAY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP), EndContainer(), SetFill(1, 1),
01669 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_DRAG_SIGNALS_DENSITY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(1, 1),
01670 NWidget(WWT_LABEL, COLOUR_DARK_GREEN, BSW_DRAG_SIGNALS_DENSITY_LABEL), SetDataTip(STR_ORANGE_INT, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(1, 1),
01671 NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
01672 NWidget(NWID_SPACER), SetFill(1, 0),
01673 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, BSW_DRAG_SIGNALS_DENSITY_DECREASE), SetMinimalSize(9, 12), SetDataTip(AWV_DECREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP),
01674 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, BSW_DRAG_SIGNALS_DENSITY_INCREASE), SetMinimalSize(9, 12), SetDataTip(AWV_INCREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP),
01675 NWidget(NWID_SPACER), SetFill(1, 0),
01676 EndContainer(),
01677 NWidget(NWID_SPACER), SetMinimalSize(0, 2), SetFill(1, 0),
01678 EndContainer(),
01679 EndContainer(),
01680 EndContainer(),
01681 };
01682
01684 static const WindowDesc _signal_builder_desc(
01685 WDP_AUTO, 0, 0,
01686 WC_BUILD_SIGNAL, WC_BUILD_TOOLBAR,
01687 WDF_UNCLICK_BUTTONS | WDF_CONSTRUCTION,
01688 _nested_signal_builder_widgets, lengthof(_nested_signal_builder_widgets)
01689 );
01690
01694 static void ShowSignalBuilder(Window *parent)
01695 {
01696 new BuildSignalWindow(&_signal_builder_desc, parent);
01697 }
01698
01700 enum BuildRailDepotWidgets {
01701 BRDW_DEPOT_NE,
01702 BRDW_DEPOT_SE,
01703 BRDW_DEPOT_SW,
01704 BRDW_DEPOT_NW,
01705 };
01706
01707 struct BuildRailDepotWindow : public PickerWindowBase {
01708 BuildRailDepotWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(parent)
01709 {
01710 this->InitNested(desc, TRANSPORT_RAIL);
01711 this->LowerWidget(_build_depot_direction + BRDW_DEPOT_NE);
01712 }
01713
01714 virtual void OnPaint()
01715 {
01716 this->DrawWidgets();
01717 }
01718
01719 virtual void DrawWidget(const Rect &r, int widget) const
01720 {
01721 if (!IsInsideMM(widget, BRDW_DEPOT_NE, BRDW_DEPOT_NW + 1)) return;
01722
01723 DrawTrainDepotSprite(r.left - 1, r.top, widget - BRDW_DEPOT_NE + DIAGDIR_NE, _cur_railtype);
01724 }
01725
01726 virtual void OnClick(Point pt, int widget)
01727 {
01728 switch (widget) {
01729 case BRDW_DEPOT_NE:
01730 case BRDW_DEPOT_SE:
01731 case BRDW_DEPOT_SW:
01732 case BRDW_DEPOT_NW:
01733 this->RaiseWidget(_build_depot_direction + BRDW_DEPOT_NE);
01734 _build_depot_direction = (DiagDirection)(widget - BRDW_DEPOT_NE);
01735 this->LowerWidget(_build_depot_direction + BRDW_DEPOT_NE);
01736 SndPlayFx(SND_15_BEEP);
01737 this->SetDirty();
01738 break;
01739 }
01740 }
01741 };
01742
01744 static const NWidgetPart _nested_build_depot_widgets[] = {
01745 NWidget(NWID_HORIZONTAL),
01746 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
01747 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_BUILD_DEPOT_TRAIN_ORIENTATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
01748 EndContainer(),
01749 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
01750 NWidget(NWID_SPACER), SetMinimalSize(0, 3),
01751 NWidget(NWID_HORIZONTAL_LTR),
01752 NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
01753 NWidget(NWID_VERTICAL),
01754 NWidget(WWT_PANEL, COLOUR_GREY, BRDW_DEPOT_NW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
01755 EndContainer(),
01756 NWidget(NWID_SPACER), SetMinimalSize(0, 2),
01757 NWidget(WWT_PANEL, COLOUR_GREY, BRDW_DEPOT_SW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
01758 EndContainer(),
01759 EndContainer(),
01760 NWidget(NWID_SPACER), SetMinimalSize(2, 0),
01761 NWidget(NWID_VERTICAL),
01762 NWidget(WWT_PANEL, COLOUR_GREY, BRDW_DEPOT_NE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
01763 EndContainer(),
01764 NWidget(NWID_SPACER), SetMinimalSize(0, 2),
01765 NWidget(WWT_PANEL, COLOUR_GREY, BRDW_DEPOT_SE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
01766 EndContainer(),
01767 EndContainer(),
01768 NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
01769 EndContainer(),
01770 NWidget(NWID_SPACER), SetMinimalSize(0, 3),
01771 EndContainer(),
01772 };
01773
01774 static const WindowDesc _build_depot_desc(
01775 WDP_AUTO, 0, 0,
01776 WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
01777 WDF_CONSTRUCTION,
01778 _nested_build_depot_widgets, lengthof(_nested_build_depot_widgets)
01779 );
01780
01781 static void ShowBuildTrainDepotPicker(Window *parent)
01782 {
01783 new BuildRailDepotWindow(&_build_depot_desc, parent);
01784 }
01785
01787 enum BuildRailWaypointWidgets {
01788 BRWW_WAYPOINT_1,
01789 BRWW_WAYPOINT_2,
01790 BRWW_WAYPOINT_3,
01791 BRWW_WAYPOINT_4,
01792 BRWW_WAYPOINT_5,
01793 BRWW_SCROLL,
01794 };
01795
01796 struct BuildRailWaypointWindow : PickerWindowBase {
01797 BuildRailWaypointWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(parent)
01798 {
01799 this->InitNested(desc, TRANSPORT_RAIL);
01800 this->hscroll.SetCapacity(5);
01801 this->hscroll.SetCount(_waypoint_count);
01802 };
01803
01804 virtual void OnPaint()
01805 {
01806 for (uint i = 0; i < this->hscroll.GetCapacity(); i++) {
01807 this->SetWidgetLoweredState(i + BRWW_WAYPOINT_1, (this->hscroll.GetPosition() + i) == _cur_waypoint_type);
01808 }
01809
01810 this->DrawWidgets();
01811
01812 for (uint i = 0; i < this->hscroll.GetCapacity(); i++) {
01813 if (this->hscroll.GetPosition() + i < this->hscroll.GetCount()) {
01814 const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, this->hscroll.GetPosition() + i);
01815 NWidgetBase *nw = this->GetWidget<NWidgetBase>(BRWW_WAYPOINT_1 + i);
01816
01817 int bottom = nw->pos_y + nw->current_y;
01818 DrawWaypointSprite(nw->pos_x + TILE_PIXELS, bottom - TILE_PIXELS, this->hscroll.GetPosition() + i, _cur_railtype);
01819
01820 if (statspec != NULL &&
01821 HasBit(statspec->callback_mask, CBM_STATION_AVAIL) &&
01822 GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) {
01823 GfxFillRect(nw->pos_x + 1, nw->pos_y + 1, nw->pos_x + nw->current_x - 2, bottom - 2, 0, FILLRECT_CHECKER);
01824 }
01825 }
01826 }
01827 }
01828
01829 virtual void OnClick(Point pt, int widget)
01830 {
01831 switch (widget) {
01832 case BRWW_WAYPOINT_1:
01833 case BRWW_WAYPOINT_2:
01834 case BRWW_WAYPOINT_3:
01835 case BRWW_WAYPOINT_4:
01836 case BRWW_WAYPOINT_5: {
01837 byte type = widget - BRWW_WAYPOINT_1 + this->hscroll.GetPosition();
01838
01839
01840 const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, type);
01841 if (statspec != NULL &&
01842 HasBit(statspec->callback_mask, CBM_STATION_AVAIL) &&
01843 GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) return;
01844
01845 _cur_waypoint_type = type;
01846 SndPlayFx(SND_15_BEEP);
01847 this->SetDirty();
01848 break;
01849 }
01850 }
01851 }
01852 };
01853
01855 static const NWidgetPart _nested_build_waypoint_widgets[] = {
01856 NWidget(NWID_HORIZONTAL),
01857 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
01858 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_WAYPOINT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
01859 EndContainer(),
01860 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
01861 NWidget(NWID_SPACER), SetMinimalSize(0, 3),
01862 NWidget(NWID_HORIZONTAL), SetPIP(3, 2, 3),
01863 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BRWW_WAYPOINT_1), SetMinimalSize(66, 60), SetDataTip(0x0, STR_WAYPOINT_GRAPHICS_TOOLTIP), EndContainer(),
01864 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BRWW_WAYPOINT_2), SetMinimalSize(66, 60), SetDataTip(0x0, STR_WAYPOINT_GRAPHICS_TOOLTIP), EndContainer(),
01865 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BRWW_WAYPOINT_3), SetMinimalSize(66, 60), SetDataTip(0x0, STR_WAYPOINT_GRAPHICS_TOOLTIP), EndContainer(),
01866 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BRWW_WAYPOINT_4), SetMinimalSize(66, 60), SetDataTip(0x0, STR_WAYPOINT_GRAPHICS_TOOLTIP), EndContainer(),
01867 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BRWW_WAYPOINT_5), SetMinimalSize(66, 60), SetDataTip(0x0, STR_WAYPOINT_GRAPHICS_TOOLTIP), EndContainer(),
01868 EndContainer(),
01869 NWidget(NWID_SPACER), SetMinimalSize(0, 3),
01870 NWidget(WWT_HSCROLLBAR, COLOUR_DARK_GREEN, BRWW_SCROLL),
01871 EndContainer(),
01872 };
01873
01874 static const WindowDesc _build_waypoint_desc(
01875 WDP_AUTO, 0, 0,
01876 WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
01877 WDF_CONSTRUCTION,
01878 _nested_build_waypoint_widgets, lengthof(_nested_build_waypoint_widgets)
01879 );
01880
01881 static void ShowBuildWaypointPicker(Window *parent)
01882 {
01883 new BuildRailWaypointWindow(&_build_waypoint_desc, parent);
01884 }
01885
01889 void InitializeRailGui()
01890 {
01891 _build_depot_direction = DIAGDIR_NW;
01892 }
01893
01898 void ReinitGuiAfterToggleElrail(bool disable)
01899 {
01900 extern RailType _last_built_railtype;
01901 if (disable && _last_built_railtype == RAILTYPE_ELECTRIC) {
01902 _last_built_railtype = _cur_railtype = RAILTYPE_RAIL;
01903 BuildRailToolbarWindow *w = dynamic_cast<BuildRailToolbarWindow *>(FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_RAIL));
01904 if (w != NULL) w->ModifyRailType(_cur_railtype);
01905 }
01906 MarkWholeScreenDirty();
01907 }
01908
01910 static void SetDefaultRailGui()
01911 {
01912 if (_local_company == COMPANY_SPECTATOR || !Company::IsValidID(_local_company)) return;
01913
01914 extern RailType _last_built_railtype;
01915 RailType rt = (RailType)_settings_client.gui.default_rail_type;
01916 if (rt >= RAILTYPE_END) {
01917 if (rt == DEF_RAILTYPE_MOST_USED) {
01918
01919 RailType count[RAILTYPE_END];
01920 memset(count, 0, sizeof(count));
01921 for (TileIndex t = 0; t < MapSize(); t++) {
01922 if (IsTileType(t, MP_RAILWAY) || IsLevelCrossingTile(t) || HasStationTileRail(t) ||
01923 (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL)) {
01924 count[GetRailType(t)]++;
01925 }
01926 }
01927
01928 rt = RAILTYPE_RAIL;
01929 for (RailType r = RAILTYPE_ELECTRIC; r < RAILTYPE_END; r++) {
01930 if (count[r] >= count[rt]) rt = r;
01931 }
01932
01933
01934 if (count[rt] == 0) rt = DEF_RAILTYPE_FIRST;
01935 }
01936 switch (rt) {
01937 case DEF_RAILTYPE_FIRST:
01938 rt = RAILTYPE_RAIL;
01939 while (rt < RAILTYPE_END && !HasRailtypeAvail(_local_company, rt)) rt++;
01940 break;
01941
01942 case DEF_RAILTYPE_LAST:
01943 rt = GetBestRailtype(_local_company);
01944 break;
01945
01946 default:
01947 break;
01948 }
01949 }
01950
01951 _last_built_railtype = _cur_railtype = rt;
01952 BuildRailToolbarWindow *w = dynamic_cast<BuildRailToolbarWindow *>(FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_RAIL));
01953 if (w != NULL) w->ModifyRailType(_cur_railtype);
01954 }
01955
01962 bool ResetSignalVariant(int32 p = 0)
01963 {
01964 SignalVariant new_variant = (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC);
01965
01966 if (new_variant != _cur_signal_variant) {
01967 Window *w = FindWindowById(WC_BUILD_SIGNAL, 0);
01968 if (w != NULL) {
01969 w->SetDirty();
01970 w->RaiseWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type);
01971 }
01972 _cur_signal_variant = new_variant;
01973 }
01974
01975 return true;
01976 }
01977
01981 void InitializeRailGUI()
01982 {
01983 SetDefaultRailGui();
01984
01985 _convert_signal_button = false;
01986 _cur_signal_type = _default_signal_type[_settings_client.gui.default_signal_type];
01987 ResetSignalVariant();
01988 }