00001
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
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,
00121 0x2400, 0x2801, 0x1800, 0x1401,
00122 0x2203, 0x0904, 0x0A05, 0x1103,
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
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) {
00200 trackbits = (_tile_fract_coords.x <= _tile_fract_coords.y) ? TRACK_BIT_RIGHT : TRACK_BIT_LEFT;
00201 }
00202
00203 if (trackbits & TRACK_BIT_HORZ) {
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
00215 static const uint cycle_bounds[] = {SIGTYPE_NORMAL | (SIGTYPE_LAST_NOPBS << 3), SIGTYPE_PBS | (SIGTYPE_LAST << 3), SIGTYPE_NORMAL | (SIGTYPE_LAST << 3)};
00216
00217
00218 uint32 p1 = track;
00219
00220 if (w != NULL) {
00221
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
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
00472 if (w->IsWidgetLowered(RTW_BUILD_STATION)) {
00473 if (_remove_button_clicked) {
00474
00475 if (!_settings_client.gui.station_dragdrop) {
00476 SetTileSelectSize(1, 1);
00477 } else {
00478 VpSetPlaceSizingLimit(-1);
00479 }
00480 } else {
00481
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;
00519
00520 if (thd->drawstyle & HT_RAIL) {
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);
00538
00539 if (thd->drawstyle == HT_RECT) {
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
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
00562
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
00627
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
00639
00640 this->SetWidgetDisabledState(RTW_REMOVE, !this->IsWidgetLowered(clicked_widget));
00641 break;
00642
00643 default:
00644
00645
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);
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
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
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},
00770 { WWT_CAPTION, RESIZE_NONE, COLOUR_DARK_GREEN, 11, 337, 0, 13, STR_100A_RAILROAD_CONSTRUCTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
00771 { WWT_STICKYBOX, RESIZE_NONE, COLOUR_DARK_GREEN, 338, 349, 0, 13, 0x0, STR_STICKY_BUTTON},
00772
00773 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 110, 113, 14, 35, 0x0, STR_NULL},
00774
00775 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 0, 21, 14, 35, SPR_IMG_RAIL_NS, STR_1018_BUILD_RAILROAD_TRACK},
00776 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 22, 43, 14, 35, SPR_IMG_RAIL_NE, STR_1018_BUILD_RAILROAD_TRACK},
00777 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 44, 65, 14, 35, SPR_IMG_RAIL_EW, STR_1018_BUILD_RAILROAD_TRACK},
00778 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 66, 87, 14, 35, SPR_IMG_RAIL_NW, STR_1018_BUILD_RAILROAD_TRACK},
00779 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 88, 109, 14, 35, SPR_IMG_AUTORAIL, STR_BUILD_AUTORAIL_TIP},
00780
00781 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 114, 135, 14, 35, SPR_IMG_DYNAMITE, STR_018D_DEMOLISH_BUILDINGS_ETC},
00782 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 136, 157, 14, 35, SPR_IMG_DEPOT_RAIL, STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING},
00783 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 158, 179, 14, 35, SPR_IMG_WAYPOINT, STR_CONVERT_RAIL_TO_WAYPOINT_TIP},
00784
00785 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 180, 221, 14, 35, SPR_IMG_RAIL_STATION, STR_101A_BUILD_RAILROAD_STATION},
00786 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 222, 243, 14, 35, SPR_IMG_RAIL_SIGNALS, STR_101B_BUILD_RAILROAD_SIGNALS},
00787 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 244, 285, 14, 35, SPR_IMG_BRIDGE, STR_101C_BUILD_RAILROAD_BRIDGE},
00788 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 286, 305, 14, 35, SPR_IMG_TUNNEL_RAIL, STR_101D_BUILD_RAILROAD_TUNNEL},
00789 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 306, 327, 14, 35, SPR_IMG_REMOVE, STR_101E_TOGGLE_BUILD_REMOVE_FOR},
00790 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 328, 349, 14, 35, SPR_IMG_CONVERT_RAIL, STR_CONVERT_RAIL_TIP},
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
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
00857
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
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
00994
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
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
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
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
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
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
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},
01279 { WWT_CAPTION, RESIZE_NONE, COLOUR_DARK_GREEN, 11, 147, 0, 13, STR_3000_RAIL_STATION_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
01280 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 0, 147, 14, 199, 0x0, STR_NULL},
01281 { WWT_PANEL, RESIZE_NONE, COLOUR_GREY, 7, 72, 26, 73, 0x0, STR_304E_SELECT_RAILROAD_STATION},
01282 { WWT_PANEL, RESIZE_NONE, COLOUR_GREY, 75, 140, 26, 73, 0x0, STR_304E_SELECT_RAILROAD_STATION},
01283
01284 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 22, 36, 87, 98, STR_00CB_1, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
01285 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 37, 51, 87, 98, STR_00CC_2, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
01286 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 52, 66, 87, 98, STR_00CD_3, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
01287 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 67, 81, 87, 98, STR_00CE_4, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
01288 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 82, 96, 87, 98, STR_00CF_5, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
01289 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 97, 111, 87, 98, STR_6, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
01290 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 112, 126, 87, 98, STR_7, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
01291
01292 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 22, 36, 112, 123, STR_00CB_1, STR_3050_SELECT_LENGTH_OF_RAILROAD},
01293 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 37, 51, 112, 123, STR_00CC_2, STR_3050_SELECT_LENGTH_OF_RAILROAD},
01294 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 52, 66, 112, 123, STR_00CD_3, STR_3050_SELECT_LENGTH_OF_RAILROAD},
01295 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 67, 81, 112, 123, STR_00CE_4, STR_3050_SELECT_LENGTH_OF_RAILROAD},
01296 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 82, 96, 112, 123, STR_00CF_5, STR_3050_SELECT_LENGTH_OF_RAILROAD},
01297 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 97, 111, 112, 123, STR_6, STR_3050_SELECT_LENGTH_OF_RAILROAD},
01298 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 112, 126, 112, 123, STR_7, STR_3050_SELECT_LENGTH_OF_RAILROAD},
01299
01300 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 37, 111, 126, 137, STR_DRAG_DROP, STR_STATION_DRAG_DROP},
01301 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 14, 73, 152, 163, STR_02DB_OFF, STR_3065_DON_T_HIGHLIGHT_COVERAGE},
01302 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 74, 133, 152, 163, STR_02DA_ON, STR_3064_HIGHLIGHT_COVERAGE_AREA},
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},
01309 { WWT_CAPTION, RESIZE_NONE, COLOUR_DARK_GREEN, 11, 147, 0, 13, STR_3000_RAIL_STATION_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
01310 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 0, 147, 14, 289, 0x0, STR_NULL},
01311 { WWT_PANEL, RESIZE_NONE, COLOUR_GREY, 7, 72, 116, 163, 0x0, STR_304E_SELECT_RAILROAD_STATION},
01312 { WWT_PANEL, RESIZE_NONE, COLOUR_GREY, 75, 140, 116, 163, 0x0, STR_304E_SELECT_RAILROAD_STATION},
01313
01314 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 22, 36, 177, 188, STR_00CB_1, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
01315 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 37, 51, 177, 188, STR_00CC_2, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
01316 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 52, 66, 177, 188, STR_00CD_3, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
01317 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 67, 81, 177, 188, STR_00CE_4, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
01318 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 82, 96, 177, 188, STR_00CF_5, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
01319 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 97, 111, 177, 188, STR_6, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
01320 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 112, 126, 177, 188, STR_7, STR_304F_SELECT_NUMBER_OF_PLATFORMS},
01321
01322 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 22, 36, 202, 213, STR_00CB_1, STR_3050_SELECT_LENGTH_OF_RAILROAD},
01323 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 37, 51, 202, 213, STR_00CC_2, STR_3050_SELECT_LENGTH_OF_RAILROAD},
01324 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 52, 66, 202, 213, STR_00CD_3, STR_3050_SELECT_LENGTH_OF_RAILROAD},
01325 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 67, 81, 202, 213, STR_00CE_4, STR_3050_SELECT_LENGTH_OF_RAILROAD},
01326 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 82, 96, 202, 213, STR_00CF_5, STR_3050_SELECT_LENGTH_OF_RAILROAD},
01327 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 97, 111, 202, 213, STR_6, STR_3050_SELECT_LENGTH_OF_RAILROAD},
01328 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 112, 126, 202, 213, STR_7, STR_3050_SELECT_LENGTH_OF_RAILROAD},
01329
01330 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 37, 111, 216, 227, STR_DRAG_DROP, STR_STATION_DRAG_DROP},
01331 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 14, 73, 242, 253, STR_02DB_OFF, STR_3065_DON_T_HIGHLIGHT_COVERAGE},
01332 { WWT_TEXTBTN, RESIZE_NONE, COLOUR_GREY, 74, 133, 242, 253, STR_02DA_ON, STR_3064_HIGHLIGHT_COVERAGE_AREA},
01333
01334
01335 { WWT_DROPDOWNIN, RESIZE_NONE, COLOUR_GREY, 7, 140, 17, 28, STR_02BD, STR_SELECT_STATION_CLASS_TIP},
01336 { WWT_MATRIX, RESIZE_NONE, COLOUR_GREY, 7, 128, 32, 102, 0x501, STR_SELECT_STATION_TYPE_TIP},
01337 { WWT_SCROLLBAR, RESIZE_NONE, COLOUR_GREY, 129, 140, 32, 102, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
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
01425 this->DrawSignalSprite(BSW_SEMAPHORE_NORM, SPR_IMG_SIGNAL_SEMAPHORE_NORM, 0, 12);
01426 this->DrawSignalSprite(BSW_SEMAPHORE_ENTRY, SPR_IMG_SIGNAL_SEMAPHORE_ENTRY, -1, 13);
01427 this->DrawSignalSprite(BSW_SEMAPHORE_EXIT, SPR_IMG_SIGNAL_SEMAPHORE_EXIT, 0, 12);
01428 this->DrawSignalSprite(BSW_SEMAPHORE_COMBO, SPR_IMG_SIGNAL_SEMAPHORE_COMBO, 0, 12);
01429 this->DrawSignalSprite(BSW_SEMAPHORE_PBS, SPR_IMG_SIGNAL_SEMAPHORE_PBS, 0, 12);
01430 this->DrawSignalSprite(BSW_SEMAPHORE_PBS_OWAY, SPR_IMG_SIGNAL_SEMAPHORE_PBS_OWAY, -1, 13);
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
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},
01494 { WWT_CAPTION, RESIZE_NONE, COLOUR_DARK_GREEN, 11, 153, 0, 13, STR_SIGNAL_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
01495
01496 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 0, 21, 14, 40, STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_NORM_TIP},
01497 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 22, 43, 14, 40, STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TIP},
01498 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 44, 65, 14, 40, STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TIP},
01499 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 66, 87, 14, 40, STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TIP},
01500 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 88, 109, 14, 40, STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_PBS_TIP},
01501 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 110, 131, 14, 40, STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TIP},
01502
01503 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 0, 21, 41, 67, STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_NORM_TIP},
01504 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 22, 43, 41, 67, STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TIP},
01505 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 44, 65, 41, 67, STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_EXIT_TIP},
01506 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 66, 87, 41, 67, STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_COMBO_TIP},
01507 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 88, 109, 41, 67, STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_PBS_TIP},
01508 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 110, 131, 41, 67, STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TIP},
01509
01510 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 132, 153, 14, 40, SPR_IMG_SIGNAL_CONVERT, STR_SIGNAL_CONVERT_TIP},
01511 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 132, 153, 41, 67, STR_NULL, STR_DRAG_SIGNALS_DENSITY_TIP},
01512 { WWT_PUSHIMGBTN, RESIZE_NONE, COLOUR_GREY, 134, 142, 54, 65, SPR_ARROW_LEFT, STR_DRAG_SIGNALS_DENSITY_DECREASE_TIP},
01513 { WWT_PUSHIMGBTN, RESIZE_NONE, COLOUR_GREY, 143, 151, 54, 65, SPR_ARROW_RIGHT, STR_DRAG_SIGNALS_DENSITY_INCREASE_TIP},
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},
01584 { WWT_CAPTION, RESIZE_NONE, COLOUR_DARK_GREEN, 11, 139, 0, 13, STR_1014_TRAIN_DEPOT_ORIENTATION, STR_018C_WINDOW_TITLE_DRAG_THIS},
01585 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 0, 139, 14, 121, 0x0, STR_NULL},
01586 { WWT_PANEL, RESIZE_NONE, COLOUR_GREY, 71, 136, 17, 66, 0x0, STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO},
01587 { WWT_PANEL, RESIZE_NONE, COLOUR_GREY, 71, 136, 69, 118, 0x0, STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO},
01588 { WWT_PANEL, RESIZE_NONE, COLOUR_GREY, 3, 68, 69, 118, 0x0, STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO},
01589 { WWT_PANEL, RESIZE_NONE, COLOUR_GREY, 3, 68, 17, 66, 0x0, STR_1020_SELECT_RAILROAD_DEPOT_ORIENTATIO},
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
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},
01681 { WWT_CAPTION, RESIZE_NONE, COLOUR_DARK_GREEN, 11, 343, 0, 13, STR_WAYPOINT, STR_018C_WINDOW_TITLE_DRAG_THIS},
01682 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 0, 343, 14, 91, 0x0, STR_NULL},
01683
01684 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 3, 68, 17, 76, 0x0, STR_WAYPOINT_GRAPHICS_TIP},
01685 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 71, 136, 17, 76, 0x0, STR_WAYPOINT_GRAPHICS_TIP},
01686 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 139, 204, 17, 76, 0x0, STR_WAYPOINT_GRAPHICS_TIP},
01687 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 207, 272, 17, 76, 0x0, STR_WAYPOINT_GRAPHICS_TIP},
01688 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 275, 340, 17, 76, 0x0, STR_WAYPOINT_GRAPHICS_TIP},
01689
01690 { WWT_HSCROLLBAR, RESIZE_NONE, COLOUR_DARK_GREEN, 1, 343, 80, 91, 0x0, STR_HSCROLL_BAR_SCROLLS_LIST},
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
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
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 }