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 #include "hotkeys.h"
00034
00035 #include "station_map.h"
00036 #include "tunnelbridge_map.h"
00037
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 StationClassID 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
00090 static void PlaceExtraDepotRail(TileIndex tile, DiagDirection dir, Track track)
00091 {
00092 if (GetRailTileType(tile) != RAIL_TILE_NORMAL) return;
00093 if ((GetTrackBits(tile) & DiagdirReachesTracks(dir)) == 0) return;
00094
00095 DoCommandP(tile, _cur_railtype, track, CMD_BUILD_SINGLE_RAIL);
00096 }
00097
00099 static const Track _place_depot_extra_track[12] = {
00100 TRACK_LEFT, TRACK_UPPER, TRACK_UPPER, TRACK_RIGHT,
00101 TRACK_X, TRACK_Y, TRACK_X, TRACK_Y,
00102 TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT, TRACK_LOWER,
00103 };
00104
00106 static const DiagDirection _place_depot_extra_dir[12] = {
00107 DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, DIAGDIR_SW,
00108 DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE, DIAGDIR_SE,
00109 DIAGDIR_NW, DIAGDIR_NE, DIAGDIR_NW, DIAGDIR_NE,
00110 };
00111
00112 void CcRailDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
00113 {
00114 if (result.Failed()) return;
00115
00116 DiagDirection dir = (DiagDirection)p2;
00117
00118 SndPlayTileFx(SND_20_SPLAT_2, tile);
00119 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
00120
00121 tile += TileOffsByDiagDir(dir);
00122
00123 if (IsTileType(tile, MP_RAILWAY)) {
00124 PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir], _place_depot_extra_track[dir]);
00125 PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir + 4], _place_depot_extra_track[dir + 4]);
00126 PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir + 8], _place_depot_extra_track[dir + 8]);
00127 }
00128 }
00129
00134 static void PlaceRail_Waypoint(TileIndex tile)
00135 {
00136 if (_remove_button_clicked) {
00137 VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_REMOVE_STATION);
00138 return;
00139 }
00140
00141 Axis axis = GetAxisForNewWaypoint(tile);
00142 if (IsValidAxis(axis)) {
00143
00144 VpStartPlaceSizing(tile, axis == AXIS_X ? VPM_FIX_X : VPM_FIX_Y, DDSP_BUILD_STATION);
00145 } else {
00146
00147
00148 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));
00149 }
00150 }
00151
00152 void CcStation(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
00153 {
00154 if (result.Failed()) return;
00155
00156 SndPlayTileFx(SND_20_SPLAT_2, tile);
00157
00158 if (_railstation.station_class == STAT_CLASS_DFLT && _railstation.station_type == 0 && !_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
00159 }
00160
00165 static void PlaceRail_Station(TileIndex tile)
00166 {
00167 if (_remove_button_clicked) {
00168 VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_REMOVE_STATION);
00169 VpSetPlaceSizingLimit(-1);
00170 } else if (_settings_client.gui.station_dragdrop) {
00171 VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_STATION);
00172 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
00173 } else {
00174 uint32 p1 = _cur_railtype | _railstation.orientation << 4 | _settings_client.gui.station_numtracks << 8 | _settings_client.gui.station_platlength << 16 | _ctrl_pressed << 24;
00175 uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16;
00176
00177 int w = _settings_client.gui.station_numtracks;
00178 int h = _settings_client.gui.station_platlength;
00179 if (!_railstation.orientation) Swap(w, h);
00180
00181 CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" };
00182 ShowSelectStationIfNeeded(cmdcont, TileArea(tile, w, h));
00183 }
00184 }
00185
00191 static void GenericPlaceSignals(TileIndex tile)
00192 {
00193 TrackBits trackbits = TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0));
00194
00195 if (trackbits & TRACK_BIT_VERT) {
00196 trackbits = (_tile_fract_coords.x <= _tile_fract_coords.y) ? TRACK_BIT_RIGHT : TRACK_BIT_LEFT;
00197 }
00198
00199 if (trackbits & TRACK_BIT_HORZ) {
00200 trackbits = (_tile_fract_coords.x + _tile_fract_coords.y <= 15) ? TRACK_BIT_UPPER : TRACK_BIT_LOWER;
00201 }
00202
00203 Track track = FindFirstTrack(trackbits);
00204
00205 if (_remove_button_clicked) {
00206 DoCommandP(tile, track, 0, CMD_REMOVE_SIGNALS | CMD_MSG(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM), CcPlaySound1E);
00207 } else {
00208 const Window *w = FindWindowById(WC_BUILD_SIGNAL, 0);
00209
00210
00211 static const uint cycle_bounds[] = {SIGTYPE_NORMAL | (SIGTYPE_LAST_NOPBS << 3), SIGTYPE_PBS | (SIGTYPE_LAST << 3), SIGTYPE_NORMAL | (SIGTYPE_LAST << 3)};
00212
00213
00214 uint32 p1 = track;
00215
00216 if (w != NULL) {
00217
00218 SB(p1, 3, 1, _ctrl_pressed);
00219 SB(p1, 4, 1, _cur_signal_variant);
00220 SB(p1, 5, 3, _cur_signal_type);
00221 SB(p1, 8, 1, _convert_signal_button);
00222 SB(p1, 9, 6, cycle_bounds[_settings_client.gui.cycle_signal_types]);
00223 } else {
00224 SB(p1, 3, 1, _ctrl_pressed);
00225 SB(p1, 4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
00226 SB(p1, 5, 3, _default_signal_type[_settings_client.gui.default_signal_type]);
00227 SB(p1, 8, 1, 0);
00228 SB(p1, 9, 6, cycle_bounds[_settings_client.gui.cycle_signal_types]);
00229 }
00230
00231 DoCommandP(tile, p1, 0, CMD_BUILD_SIGNALS |
00232 CMD_MSG((w != NULL && _convert_signal_button) ? STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE),
00233 CcPlaySound1E);
00234 }
00235 }
00236
00242 static void PlaceRail_Bridge(TileIndex tile, Window *w)
00243 {
00244 if (IsBridgeTile(tile)) {
00245 TileIndex other_tile = GetOtherTunnelBridgeEnd(tile);
00246 Point pt = {0, 0};
00247 w->OnPlaceMouseUp(VPM_X_OR_Y, DDSP_BUILD_BRIDGE, pt, tile, other_tile);
00248 } else {
00249 VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE);
00250 }
00251 }
00252
00254 void CcBuildRailTunnel(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
00255 {
00256 if (result.Succeeded()) {
00257 SndPlayTileFx(SND_20_SPLAT_2, tile);
00258 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
00259 } else {
00260 SetRedErrorSquare(_build_tunnel_endtile);
00261 }
00262 }
00263
00264
00266 enum RailToolbarWidgets {
00267 RTW_CAPTION,
00268 RTW_BUILD_NS,
00269 RTW_BUILD_X,
00270 RTW_BUILD_EW,
00271 RTW_BUILD_Y,
00272 RTW_AUTORAIL,
00273 RTW_DEMOLISH,
00274 RTW_BUILD_DEPOT,
00275 RTW_BUILD_WAYPOINT,
00276 RTW_BUILD_STATION,
00277 RTW_BUILD_SIGNALS,
00278 RTW_BUILD_BRIDGE,
00279 RTW_BUILD_TUNNEL,
00280 RTW_REMOVE,
00281 RTW_CONVERT_RAIL,
00282 };
00283
00284
00289 static void ToggleRailButton_Remove(Window *w)
00290 {
00291 DeleteWindowById(WC_SELECT_STATION, 0);
00292 w->ToggleWidgetLoweredState(RTW_REMOVE);
00293 w->SetWidgetDirty(RTW_REMOVE);
00294 _remove_button_clicked = w->IsWidgetLowered(RTW_REMOVE);
00295 SetSelectionRed(_remove_button_clicked);
00296 }
00297
00303 static bool RailToolbar_CtrlChanged(Window *w)
00304 {
00305 if (w->IsWidgetDisabled(RTW_REMOVE)) return false;
00306
00307
00308 for (uint i = RTW_BUILD_NS; i <= RTW_BUILD_STATION; i++) {
00309 if ((i <= RTW_AUTORAIL || i >= RTW_BUILD_WAYPOINT) && w->IsWidgetLowered(i)) {
00310 ToggleRailButton_Remove(w);
00311 return true;
00312 }
00313 }
00314
00315 return false;
00316 }
00317
00318
00324 static void BuildRailClick_Remove(Window *w)
00325 {
00326 if (w->IsWidgetDisabled(RTW_REMOVE)) return;
00327 ToggleRailButton_Remove(w);
00328 SndPlayFx(SND_15_BEEP);
00329
00330
00331 if (w->IsWidgetLowered(RTW_BUILD_STATION)) {
00332 if (_remove_button_clicked) {
00333
00334 if (!_settings_client.gui.station_dragdrop) {
00335 SetTileSelectSize(1, 1);
00336 } else {
00337 VpSetPlaceSizingLimit(-1);
00338 }
00339 } else {
00340
00341 if (!_settings_client.gui.station_dragdrop) {
00342 int x = _settings_client.gui.station_numtracks;
00343 int y = _settings_client.gui.station_platlength;
00344 if (_railstation.orientation == 0) Swap(x, y);
00345 SetTileSelectSize(x, y);
00346 } else {
00347 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
00348 }
00349 }
00350 }
00351 }
00352
00353 static void DoRailroadTrack(int mode)
00354 {
00355 DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 4),
00356 _remove_button_clicked ?
00357 CMD_REMOVE_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) :
00358 CMD_BUILD_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK));
00359 }
00360
00361 static void HandleAutodirPlacement()
00362 {
00363 TileHighlightData *thd = &_thd;
00364 int trackstat = thd->drawstyle & 0xF;
00365
00366 if (thd->drawstyle & HT_RAIL) {
00367 GenericPlaceRail(TileVirtXY(thd->selend.x, thd->selend.y), trackstat);
00368 return;
00369 }
00370
00371 DoRailroadTrack(trackstat);
00372 }
00373
00380 static void HandleAutoSignalPlacement()
00381 {
00382 TileHighlightData *thd = &_thd;
00383 uint32 p2 = GB(thd->drawstyle, 0, 3);
00384
00385 if (thd->drawstyle == HT_RECT) {
00386 GenericPlaceSignals(TileVirtXY(thd->selend.x, thd->selend.y));
00387 return;
00388 }
00389
00390 const Window *w = FindWindowById(WC_BUILD_SIGNAL, 0);
00391
00392 if (w != NULL) {
00393
00394 SB(p2, 3, 1, 0);
00395 SB(p2, 4, 1, _cur_signal_variant);
00396 SB(p2, 6, 1, _ctrl_pressed);
00397 SB(p2, 7, 3, _cur_signal_type);
00398 SB(p2, 24, 8, _settings_client.gui.drag_signals_density);
00399 } else {
00400 SB(p2, 3, 1, 0);
00401 SB(p2, 4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
00402 SB(p2, 6, 1, _ctrl_pressed);
00403 SB(p2, 7, 3, _default_signal_type[_settings_client.gui.default_signal_type]);
00404 SB(p2, 24, 8, _settings_client.gui.drag_signals_density);
00405 }
00406
00407
00408
00409 DoCommandP(TileVirtXY(thd->selstart.x, thd->selstart.y), TileVirtXY(thd->selend.x, thd->selend.y), p2,
00410 _remove_button_clicked ?
00411 CMD_REMOVE_SIGNAL_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM) :
00412 CMD_BUILD_SIGNAL_TRACK | CMD_MSG(STR_ERROR_CAN_T_BUILD_SIGNALS_HERE),
00413 CcPlaySound1E);
00414 }
00415
00416
00418 struct BuildRailToolbarWindow : Window {
00419 RailType railtype;
00420 int last_user_action;
00421
00422 BuildRailToolbarWindow(const WindowDesc *desc, WindowNumber window_number, RailType railtype) : Window()
00423 {
00424 this->InitNested(desc);
00425 this->SetupRailToolbar(railtype);
00426 this->DisableWidget(RTW_REMOVE);
00427 this->last_user_action = WIDGET_LIST_END;
00428
00429 if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
00430 }
00431
00432 ~BuildRailToolbarWindow()
00433 {
00434 if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false);
00435 }
00436
00441 void SetupRailToolbar(RailType railtype)
00442 {
00443 this->railtype = railtype;
00444 const RailtypeInfo *rti = GetRailTypeInfo(railtype);
00445
00446 assert(railtype < RAILTYPE_END);
00447 this->GetWidget<NWidgetCore>(RTW_BUILD_NS)->widget_data = rti->gui_sprites.build_ns_rail;
00448 this->GetWidget<NWidgetCore>(RTW_BUILD_X)->widget_data = rti->gui_sprites.build_x_rail;
00449 this->GetWidget<NWidgetCore>(RTW_BUILD_EW)->widget_data = rti->gui_sprites.build_ew_rail;
00450 this->GetWidget<NWidgetCore>(RTW_BUILD_Y)->widget_data = rti->gui_sprites.build_y_rail;
00451 this->GetWidget<NWidgetCore>(RTW_AUTORAIL)->widget_data = rti->gui_sprites.auto_rail;
00452 this->GetWidget<NWidgetCore>(RTW_BUILD_DEPOT)->widget_data = rti->gui_sprites.build_depot;
00453 this->GetWidget<NWidgetCore>(RTW_CONVERT_RAIL)->widget_data = rti->gui_sprites.convert_rail;
00454 this->GetWidget<NWidgetCore>(RTW_BUILD_TUNNEL)->widget_data = rti->gui_sprites.build_tunnel;
00455 }
00456
00461 void ModifyRailType(RailType railtype)
00462 {
00463 this->SetupRailToolbar(railtype);
00464 this->ReInit();
00465 }
00466
00467 void UpdateRemoveWidgetStatus(int clicked_widget)
00468 {
00469 switch (clicked_widget) {
00470 case RTW_REMOVE:
00471
00472
00473 return;
00474
00475 case RTW_BUILD_NS:
00476 case RTW_BUILD_X:
00477 case RTW_BUILD_EW:
00478 case RTW_BUILD_Y:
00479 case RTW_AUTORAIL:
00480 case RTW_BUILD_WAYPOINT:
00481 case RTW_BUILD_STATION:
00482 case RTW_BUILD_SIGNALS:
00483
00484
00485 this->SetWidgetDisabledState(RTW_REMOVE, !this->IsWidgetLowered(clicked_widget));
00486 break;
00487
00488 default:
00489
00490
00491 this->DisableWidget(RTW_REMOVE);
00492 this->RaiseWidget(RTW_REMOVE);
00493 break;
00494 }
00495 }
00496
00497 virtual void SetStringParameters(int widget) const
00498 {
00499 if (widget == RTW_CAPTION) {
00500 const RailtypeInfo *rti = GetRailTypeInfo(this->railtype);
00501 if (rti->max_speed > 0) {
00502 SetDParam(0, STR_TOOLBAR_RAILTYPE_VELOCITY);
00503 SetDParam(1, rti->strings.toolbar_caption);
00504 SetDParam(2, rti->max_speed);
00505 } else {
00506 SetDParam(0, rti->strings.toolbar_caption);
00507 }
00508 }
00509 }
00510
00511 virtual void OnClick(Point pt, int widget, int click_count)
00512 {
00513 if (widget < RTW_BUILD_NS) return;
00514
00515 _remove_button_clicked = false;
00516 switch (widget) {
00517 case RTW_BUILD_NS:
00518 HandlePlacePushButton(this, RTW_BUILD_NS, GetRailTypeInfo(_cur_railtype)->cursor.rail_ns, HT_LINE | HT_DIR_VL, NULL);
00519 this->last_user_action = widget;
00520 break;
00521
00522 case RTW_BUILD_X:
00523 HandlePlacePushButton(this, RTW_BUILD_X, GetRailTypeInfo(_cur_railtype)->cursor.rail_swne, HT_LINE | HT_DIR_X, NULL);
00524 this->last_user_action = widget;
00525 break;
00526
00527 case RTW_BUILD_EW:
00528 HandlePlacePushButton(this, RTW_BUILD_EW, GetRailTypeInfo(_cur_railtype)->cursor.rail_ew, HT_LINE | HT_DIR_HL, NULL);
00529 this->last_user_action = widget;
00530 break;
00531
00532 case RTW_BUILD_Y:
00533 HandlePlacePushButton(this, RTW_BUILD_Y, GetRailTypeInfo(_cur_railtype)->cursor.rail_nwse, HT_LINE | HT_DIR_Y, NULL);
00534 this->last_user_action = widget;
00535 break;
00536
00537 case RTW_AUTORAIL:
00538 HandlePlacePushButton(this, RTW_AUTORAIL, GetRailTypeInfo(_cur_railtype)->cursor.autorail, HT_RAIL, NULL);
00539 this->last_user_action = widget;
00540 break;
00541
00542 case RTW_DEMOLISH:
00543 HandlePlacePushButton(this, RTW_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL, NULL);
00544 this->last_user_action = widget;
00545 break;
00546
00547 case RTW_BUILD_DEPOT:
00548 if (HandlePlacePushButton(this, RTW_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, HT_RECT, NULL)) {
00549 ShowBuildTrainDepotPicker(this);
00550 this->last_user_action = widget;
00551 }
00552 break;
00553
00554 case RTW_BUILD_WAYPOINT:
00555 this->last_user_action = widget;
00556 _waypoint_count = StationClass::GetCount(STAT_CLASS_WAYP);
00557 if (HandlePlacePushButton(this, RTW_BUILD_WAYPOINT, SPR_CURSOR_WAYPOINT, HT_RECT, NULL) && _waypoint_count > 1) {
00558 ShowBuildWaypointPicker(this);
00559 }
00560 break;
00561
00562 case RTW_BUILD_STATION:
00563 if (HandlePlacePushButton(this, RTW_BUILD_STATION, SPR_CURSOR_RAIL_STATION, HT_RECT, NULL)) {
00564 ShowStationBuilder(this);
00565 this->last_user_action = widget;
00566 }
00567 break;
00568
00569 case RTW_BUILD_SIGNALS: {
00570 this->last_user_action = widget;
00571 bool started = HandlePlacePushButton(this, RTW_BUILD_SIGNALS, ANIMCURSOR_BUILDSIGNALS, HT_RECT, NULL);
00572 if (started && _settings_client.gui.enable_signal_gui != _ctrl_pressed) {
00573 ShowSignalBuilder(this);
00574 }
00575 break;
00576 }
00577
00578 case RTW_BUILD_BRIDGE:
00579 HandlePlacePushButton(this, RTW_BUILD_BRIDGE, SPR_CURSOR_BRIDGE, HT_RECT, NULL);
00580 this->last_user_action = widget;
00581 break;
00582
00583 case RTW_BUILD_TUNNEL:
00584 HandlePlacePushButton(this, RTW_BUILD_TUNNEL, GetRailTypeInfo(_cur_railtype)->cursor.tunnel, HT_SPECIAL, NULL);
00585 this->last_user_action = widget;
00586 break;
00587
00588 case RTW_REMOVE:
00589 BuildRailClick_Remove(this);
00590 break;
00591
00592 case RTW_CONVERT_RAIL:
00593 HandlePlacePushButton(this, RTW_CONVERT_RAIL, GetRailTypeInfo(_cur_railtype)->cursor.convert, HT_RECT, NULL);
00594 this->last_user_action = widget;
00595 break;
00596
00597 default: NOT_REACHED();
00598 }
00599 this->UpdateRemoveWidgetStatus(widget);
00600 if (_ctrl_pressed) RailToolbar_CtrlChanged(this);
00601 }
00602
00603 virtual EventState OnKeyPress(uint16 key, uint16 keycode)
00604 {
00605 int num = CheckHotkeyMatch(railtoolbar_hotkeys, keycode, this);
00606 if (num == -1) return ES_NOT_HANDLED;
00607 this->OnClick(Point(), num, 1);
00608 MarkTileDirtyByTile(TileVirtXY(_thd.pos.x, _thd.pos.y));
00609 return ES_HANDLED;
00610 }
00611
00612 virtual void OnPlaceObject(Point pt, TileIndex tile)
00613 {
00614 switch (this->last_user_action) {
00615 case RTW_BUILD_NS:
00616 VpStartPlaceSizing(tile, VPM_FIX_VERTICAL | VPM_RAILDIRS, DDSP_PLACE_RAIL);
00617 break;
00618
00619 case RTW_BUILD_X:
00620 VpStartPlaceSizing(tile, VPM_FIX_Y | VPM_RAILDIRS, DDSP_PLACE_RAIL);
00621 break;
00622
00623 case RTW_BUILD_EW:
00624 VpStartPlaceSizing(tile, VPM_FIX_HORIZONTAL | VPM_RAILDIRS, DDSP_PLACE_RAIL);
00625 break;
00626
00627 case RTW_BUILD_Y:
00628 VpStartPlaceSizing(tile, VPM_FIX_X | VPM_RAILDIRS, DDSP_PLACE_RAIL);
00629 break;
00630
00631 case RTW_AUTORAIL:
00632 VpStartPlaceSizing(tile, VPM_RAILDIRS, DDSP_PLACE_RAIL);
00633 break;
00634
00635 case RTW_DEMOLISH:
00636 PlaceProc_DemolishArea(tile);
00637 break;
00638
00639 case RTW_BUILD_DEPOT:
00640 DoCommandP(tile, _cur_railtype, _build_depot_direction,
00641 CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT),
00642 CcRailDepot);
00643 break;
00644
00645 case RTW_BUILD_WAYPOINT:
00646 PlaceRail_Waypoint(tile);
00647 break;
00648
00649 case RTW_BUILD_STATION:
00650 PlaceRail_Station(tile);
00651 break;
00652
00653 case RTW_BUILD_SIGNALS:
00654 VpStartPlaceSizing(tile, VPM_SIGNALDIRS, DDSP_BUILD_SIGNALS);
00655 break;
00656
00657 case RTW_BUILD_BRIDGE:
00658 PlaceRail_Bridge(tile, this);
00659 break;
00660
00661 case RTW_BUILD_TUNNEL:
00662 DoCommandP(tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel);
00663 break;
00664
00665 case RTW_CONVERT_RAIL:
00666 VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CONVERT_RAIL);
00667 break;
00668
00669 default: NOT_REACHED();
00670 }
00671 }
00672
00673 virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
00674 {
00675
00676 if (FindWindowById(WC_BUILD_SIGNAL, 0) != NULL && _convert_signal_button && this->IsWidgetLowered(RTW_BUILD_SIGNALS)) return;
00677
00678 VpSelectTilesWithMethod(pt.x, pt.y, select_method);
00679 }
00680
00681 virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
00682 {
00683 if (pt.x != -1) {
00684 switch (select_proc) {
00685 default: NOT_REACHED();
00686 case DDSP_BUILD_BRIDGE:
00687 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
00688 ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_RAIL, _cur_railtype);
00689 break;
00690
00691 case DDSP_PLACE_RAIL:
00692 HandleAutodirPlacement();
00693 break;
00694
00695 case DDSP_BUILD_SIGNALS:
00696 HandleAutoSignalPlacement();
00697 break;
00698
00699 case DDSP_DEMOLISH_AREA:
00700 GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
00701 break;
00702
00703 case DDSP_CONVERT_RAIL:
00704 DoCommandP(end_tile, start_tile, _cur_railtype, CMD_CONVERT_RAIL | CMD_MSG(STR_ERROR_CAN_T_CONVERT_RAIL), CcPlaySound10);
00705 break;
00706
00707 case DDSP_REMOVE_STATION:
00708 case DDSP_BUILD_STATION:
00709 if (this->IsWidgetLowered(RTW_BUILD_STATION)) {
00710
00711 if (_remove_button_clicked) {
00712 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);
00713 } else {
00714 HandleStationPlacement(start_tile, end_tile);
00715 }
00716 } else {
00717
00718 if (_remove_button_clicked) {
00719 DoCommandP(end_tile, start_tile, _ctrl_pressed ? 0 : 1, CMD_REMOVE_FROM_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT), CcPlaySound1E);
00720 } else {
00721 TileArea ta(start_tile, end_tile);
00722 uint32 p1 = _cur_railtype | (select_method == VPM_FIX_X ? AXIS_X : AXIS_Y) << 4 | ta.w << 8 | ta.h << 16 | _ctrl_pressed << 24;
00723 uint32 p2 = STAT_CLASS_WAYP | _cur_waypoint_type << 8 | INVALID_STATION << 16;
00724
00725 CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT), CcPlaySound1E, "" };
00726 ShowSelectWaypointIfNeeded(cmdcont, ta);
00727 }
00728 }
00729 break;
00730 }
00731 }
00732 }
00733
00734 virtual void OnPlaceObjectAbort()
00735 {
00736 this->RaiseButtons();
00737 this->DisableWidget(RTW_REMOVE);
00738 this->SetWidgetDirty(RTW_REMOVE);
00739
00740 DeleteWindowById(WC_BUILD_SIGNAL, TRANSPORT_RAIL);
00741 DeleteWindowById(WC_BUILD_STATION, TRANSPORT_RAIL);
00742 DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_RAIL);
00743 DeleteWindowById(WC_SELECT_STATION, 0);
00744 DeleteWindowByClass(WC_BUILD_BRIDGE);
00745 }
00746
00747 virtual void OnPlacePresize(Point pt, TileIndex tile)
00748 {
00749 DoCommand(tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, DC_AUTO, CMD_BUILD_TUNNEL);
00750 VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
00751 }
00752
00753 virtual EventState OnCTRLStateChange()
00754 {
00755
00756 if (!this->IsWidgetLowered(RTW_BUILD_STATION) && !this->IsWidgetLowered(RTW_BUILD_WAYPOINT) && RailToolbar_CtrlChanged(this)) return ES_HANDLED;
00757 return ES_NOT_HANDLED;
00758 }
00759
00760 static Hotkey<BuildRailToolbarWindow> railtoolbar_hotkeys[];
00761 };
00762
00763 const uint16 _railtoolbar_autorail_keys[] = {'5', 'A' | WKC_GLOBAL_HOTKEY, 0};
00764
00765 Hotkey<BuildRailToolbarWindow> BuildRailToolbarWindow::railtoolbar_hotkeys[] = {
00766 Hotkey<BuildRailToolbarWindow>('1', "build_ns", RTW_BUILD_NS),
00767 Hotkey<BuildRailToolbarWindow>('2', "build_x", RTW_BUILD_X),
00768 Hotkey<BuildRailToolbarWindow>('3', "build_ew", RTW_BUILD_EW),
00769 Hotkey<BuildRailToolbarWindow>('4', "build_y", RTW_BUILD_Y),
00770 Hotkey<BuildRailToolbarWindow>(_railtoolbar_autorail_keys, "autorail", RTW_AUTORAIL),
00771 Hotkey<BuildRailToolbarWindow>('6', "demolish", RTW_DEMOLISH),
00772 Hotkey<BuildRailToolbarWindow>('7', "depot", RTW_BUILD_DEPOT),
00773 Hotkey<BuildRailToolbarWindow>('8', "waypoint", RTW_BUILD_WAYPOINT),
00774 Hotkey<BuildRailToolbarWindow>('9', "station", RTW_BUILD_STATION),
00775 Hotkey<BuildRailToolbarWindow>('S', "signal", RTW_BUILD_SIGNALS),
00776 Hotkey<BuildRailToolbarWindow>('B', "bridge", RTW_BUILD_BRIDGE),
00777 Hotkey<BuildRailToolbarWindow>('T', "tunnel", RTW_BUILD_TUNNEL),
00778 Hotkey<BuildRailToolbarWindow>('R', "remove", RTW_REMOVE),
00779 Hotkey<BuildRailToolbarWindow>('C', "convert", RTW_CONVERT_RAIL),
00780 HOTKEY_LIST_END(BuildRailToolbarWindow)
00781 };
00782 Hotkey<BuildRailToolbarWindow> *_railtoolbar_hotkeys = BuildRailToolbarWindow::railtoolbar_hotkeys;
00783
00784 static const NWidgetPart _nested_build_rail_widgets[] = {
00785 NWidget(NWID_HORIZONTAL),
00786 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
00787 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, RTW_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00788 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
00789 EndContainer(),
00790 NWidget(NWID_HORIZONTAL),
00791 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_NS),
00792 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_RAIL_NS, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
00793 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_X),
00794 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_RAIL_NE, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
00795 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_EW),
00796 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_RAIL_EW, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
00797 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_Y),
00798 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_RAIL_NW, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
00799 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_AUTORAIL),
00800 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTORAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL),
00801
00802 NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetMinimalSize(4, 22), SetDataTip(0x0, STR_NULL), EndContainer(),
00803
00804 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_DEMOLISH),
00805 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
00806 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_DEPOT),
00807 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DEPOT_RAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING),
00808 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_WAYPOINT),
00809 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_WAYPOINT, STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT),
00810 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_STATION),
00811 SetFill(0, 1), SetMinimalSize(42, 22), SetDataTip(SPR_IMG_RAIL_STATION, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION),
00812 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_SIGNALS),
00813 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_RAIL_SIGNALS, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS),
00814 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_BRIDGE),
00815 SetFill(0, 1), SetMinimalSize(42, 22), SetDataTip(SPR_IMG_BRIDGE, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE),
00816 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_TUNNEL),
00817 SetFill(0, 1), SetMinimalSize(20, 22), SetDataTip(SPR_IMG_TUNNEL_RAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL),
00818 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_REMOVE),
00819 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE, STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR),
00820 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_CONVERT_RAIL),
00821 SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_CONVERT_RAIL, STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL),
00822 EndContainer(),
00823 };
00824
00825 static const WindowDesc _build_rail_desc(
00826 WDP_ALIGN_TOOLBAR, 0, 0,
00827 WC_BUILD_TOOLBAR, WC_NONE,
00828 WDF_CONSTRUCTION,
00829 _nested_build_rail_widgets, lengthof(_nested_build_rail_widgets)
00830 );
00831
00832
00841 Window *ShowBuildRailToolbar(RailType railtype)
00842 {
00843 if (!Company::IsValidID(_local_company)) return NULL;
00844 if (!ValParamRailtype(railtype)) return NULL;
00845
00846 DeleteWindowByClass(WC_BUILD_TOOLBAR);
00847 _cur_railtype = railtype;
00848 _remove_button_clicked = false;
00849 return new BuildRailToolbarWindow(&_build_rail_desc, TRANSPORT_RAIL, railtype);
00850 }
00851
00852 EventState RailToolbarGlobalHotkeys(uint16 key, uint16 keycode)
00853 {
00854 extern RailType _last_built_railtype;
00855 int num = CheckHotkeyMatch<BuildRailToolbarWindow>(_railtoolbar_hotkeys, keycode, NULL, true);
00856 if (num == -1) return ES_NOT_HANDLED;
00857 Window *w = ShowBuildRailToolbar(_last_built_railtype);
00858 if (w == NULL) return ES_NOT_HANDLED;
00859 return w->OnKeyPress(key, keycode);
00860 }
00861
00862
00863
00864
00865 static void HandleStationPlacement(TileIndex start, TileIndex end)
00866 {
00867 TileArea ta(start, end);
00868 uint numtracks = ta.w;
00869 uint platlength = ta.h;
00870
00871 if (_railstation.orientation == AXIS_X) Swap(numtracks, platlength);
00872
00873 uint32 p1 = _cur_railtype | _railstation.orientation << 4 | numtracks << 8 | platlength << 16 | _ctrl_pressed << 24;
00874 uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16;
00875
00876 CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" };
00877 ShowSelectStationIfNeeded(cmdcont, ta);
00878 }
00879
00881 enum BuildRailStationWidgets {
00882 BRSW_BACKGROUND,
00883
00884 BRSW_PLATFORM_DIR_X,
00885 BRSW_PLATFORM_DIR_Y,
00886
00887 BRSW_PLATFORM_NUM_1,
00888 BRSW_PLATFORM_NUM_2,
00889 BRSW_PLATFORM_NUM_3,
00890 BRSW_PLATFORM_NUM_4,
00891 BRSW_PLATFORM_NUM_5,
00892 BRSW_PLATFORM_NUM_6,
00893 BRSW_PLATFORM_NUM_7,
00894
00895 BRSW_PLATFORM_LEN_1,
00896 BRSW_PLATFORM_LEN_2,
00897 BRSW_PLATFORM_LEN_3,
00898 BRSW_PLATFORM_LEN_4,
00899 BRSW_PLATFORM_LEN_5,
00900 BRSW_PLATFORM_LEN_6,
00901 BRSW_PLATFORM_LEN_7,
00902
00903 BRSW_PLATFORM_DRAG_N_DROP,
00904
00905 BRSW_HIGHLIGHT_OFF,
00906 BRSW_HIGHLIGHT_ON,
00907
00908 BRSW_SHOW_NEWST_ADDITIONS,
00909 BRSW_NEWST_DROPDOWN,
00910 BRSW_NEWST_LIST,
00911 BRSW_NEWST_SCROLL,
00912
00913 BRSW_PLATFORM_NUM_BEGIN = BRSW_PLATFORM_NUM_1 - 1,
00914 BRSW_PLATFORM_LEN_BEGIN = BRSW_PLATFORM_LEN_1 - 1,
00915 };
00916
00917 struct BuildRailStationWindow : public PickerWindowBase {
00918 private:
00919 uint line_height;
00920 Scrollbar *vscroll;
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 < StationClass::GetCount(); i++) {
00957 if (i == STAT_CLASS_WAYP) continue;
00958 list->push_back(new DropDownListStringItem(StationClass::GetName((StationClassID)i), i, false));
00959 }
00960
00961 return list;
00962 }
00963
00964 public:
00965 BuildRailStationWindow(const WindowDesc *desc, Window *parent, bool newstation) : PickerWindowBase(parent)
00966 {
00967 this->CreateNestedTree(desc);
00968 this->vscroll = this->GetScrollbar(BRSW_NEWST_SCROLL);
00969 NWidgetStacked *newst_additions = this->GetWidget<NWidgetStacked>(BRSW_SHOW_NEWST_ADDITIONS);
00970 newst_additions->SetDisplayedPlane(newstation ? 0 : SZSP_NONE);
00971 this->FinishInitNested(desc, TRANSPORT_RAIL);
00972
00973 this->LowerWidget(_railstation.orientation + BRSW_PLATFORM_DIR_X);
00974 if (_settings_client.gui.station_dragdrop) {
00975 this->LowerWidget(BRSW_PLATFORM_DRAG_N_DROP);
00976 } else {
00977 this->LowerWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
00978 this->LowerWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
00979 }
00980 this->SetWidgetLoweredState(BRSW_HIGHLIGHT_OFF, !_settings_client.gui.station_show_coverage);
00981 this->SetWidgetLoweredState(BRSW_HIGHLIGHT_ON, _settings_client.gui.station_show_coverage);
00982
00983 _railstation.newstations = newstation;
00984
00985 if (newstation) {
00986 _railstation.station_count = StationClass::GetCount(_railstation.station_class);
00987
00988 this->vscroll->SetCount(_railstation.station_count);
00989 this->vscroll->SetCapacity(GB(this->GetWidget<NWidgetCore>(BRSW_NEWST_LIST)->widget_data, MAT_ROW_START, MAT_ROW_BITS));
00990 this->vscroll->SetPosition(Clamp(_railstation.station_type - 2, 0, max(this->vscroll->GetCount() - this->vscroll->GetCapacity(), 0)));
00991 } else {
00992
00993
00994 _railstation.station_class = STAT_CLASS_DFLT;
00995 _railstation.station_type = 0;
00996 }
00997 }
00998
00999 virtual ~BuildRailStationWindow()
01000 {
01001 DeleteWindowById(WC_SELECT_STATION, 0);
01002 }
01003
01004 virtual void OnPaint()
01005 {
01006 bool newstations = _railstation.newstations;
01007 const StationSpec *statspec = newstations ? StationClass::Get(_railstation.station_class, _railstation.station_type) : NULL;
01008
01009 if (_settings_client.gui.station_dragdrop) {
01010 SetTileSelectSize(1, 1);
01011 } else {
01012 int x = _settings_client.gui.station_numtracks;
01013 int y = _settings_client.gui.station_platlength;
01014 if (_railstation.orientation == AXIS_X) Swap(x, y);
01015 if (!_remove_button_clicked) {
01016 SetTileSelectSize(x, y);
01017 }
01018 }
01019
01020 int rad = (_settings_game.station.modified_catchment) ? CA_TRAIN : CA_UNMODIFIED;
01021
01022 if (_settings_client.gui.station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
01023
01024 for (uint bits = 0; bits < 7; bits++) {
01025 bool disable = bits >= _settings_game.station.station_spread;
01026 if (statspec == NULL) {
01027 this->SetWidgetDisabledState(bits + BRSW_PLATFORM_NUM_1, disable);
01028 this->SetWidgetDisabledState(bits + BRSW_PLATFORM_LEN_1, disable);
01029 } else {
01030 this->SetWidgetDisabledState(bits + BRSW_PLATFORM_NUM_1, HasBit(statspec->disallowed_platforms, bits) || disable);
01031 this->SetWidgetDisabledState(bits + BRSW_PLATFORM_LEN_1, HasBit(statspec->disallowed_lengths, bits) || disable);
01032 }
01033 }
01034
01035 this->DrawWidgets();
01036
01037
01038 int top = this->GetWidget<NWidgetBase>(BRSW_HIGHLIGHT_ON)->pos_y + this->GetWidget<NWidgetBase>(BRSW_HIGHLIGHT_ON)->current_y + WD_PAR_VSEP_NORMAL;
01039 NWidgetBase *back_nwi = this->GetWidget<NWidgetBase>(BRSW_BACKGROUND);
01040 int right = back_nwi->pos_x + back_nwi->current_x;
01041 int bottom = back_nwi->pos_y + back_nwi->current_y;
01042 top = DrawStationCoverageAreaText(back_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, SCT_ALL, rad, false) + WD_PAR_VSEP_NORMAL;
01043 top = DrawStationCoverageAreaText(back_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, SCT_ALL, rad, true) + WD_PAR_VSEP_NORMAL;
01044
01045 if (top > bottom || (top < bottom && back_nwi->current_y > back_nwi->smallest_y)) {
01046 ResizeWindow(this, 0, top - bottom);
01047 }
01048 }
01049
01050 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
01051 {
01052 switch (widget) {
01053 case BRSW_NEWST_DROPDOWN: {
01054 Dimension d = {0, 0};
01055 for (uint i = 0; i < StationClass::GetCount(); i++) {
01056 if (i == STAT_CLASS_WAYP) continue;
01057 SetDParam(0, StationClass::GetName((StationClassID)i));
01058 d = maxdim(d, GetStringBoundingBox(STR_BLACK_STRING));
01059 }
01060 d.width += padding.width;
01061 d.height += padding.height;
01062 *size = maxdim(*size, d);
01063 break;
01064 }
01065 case BRSW_NEWST_LIST: {
01066 Dimension d = GetStringBoundingBox(STR_STATION_CLASS_DFLT);
01067 for (StationClassID statclass = STAT_CLASS_BEGIN; statclass < (StationClassID)StationClass::GetCount(); statclass++) {
01068 if (statclass == STAT_CLASS_WAYP) continue;
01069 for (uint16 j = 0; j < StationClass::GetCount(statclass); j++) {
01070 const StationSpec *statspec = StationClass::Get(statclass, j);
01071 if (statspec != NULL && statspec->name != 0) d = maxdim(d, GetStringBoundingBox(statspec->name));
01072 }
01073 }
01074 size->width = max(size->width, d.width + padding.width);
01075
01076 this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
01077 size->height = GB(this->GetWidget<NWidgetCore>(widget)->widget_data, MAT_ROW_START, MAT_ROW_BITS) * this->line_height;
01078 break;
01079 }
01080 }
01081 }
01082
01083 virtual void DrawWidget(const Rect &r, int widget) const
01084 {
01085 DrawPixelInfo tmp_dpi;
01086
01087 switch (widget) {
01088 case BRSW_PLATFORM_DIR_X:
01089
01090 if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left + 1, r.bottom - r.top + 1)) {
01091 DrawPixelInfo *old_dpi = _cur_dpi;
01092 _cur_dpi = &tmp_dpi;
01093 if (!DrawStationTile(32, 16, _cur_railtype, AXIS_X, _railstation.station_class, _railstation.station_type)) {
01094 StationPickerDrawSprite(32, 16, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2);
01095 }
01096 _cur_dpi = old_dpi;
01097 }
01098 break;
01099
01100 case BRSW_PLATFORM_DIR_Y:
01101
01102 if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left + 1, r.bottom - r.top + 1)) {
01103 DrawPixelInfo *old_dpi = _cur_dpi;
01104 _cur_dpi = &tmp_dpi;
01105 if (!DrawStationTile(32, 16, _cur_railtype, AXIS_Y, _railstation.station_class, _railstation.station_type)) {
01106 StationPickerDrawSprite(32, 16, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 3);
01107 }
01108 _cur_dpi = old_dpi;
01109 }
01110 break;
01111
01112 case BRSW_NEWST_LIST: {
01113 uint y = r.top;
01114 for (uint16 i = this->vscroll->GetPosition(); i < _railstation.station_count && this->vscroll->IsVisible(i); i++) {
01115 const StationSpec *statspec = StationClass::Get(_railstation.station_class, i);
01116
01117 StringID str = STR_STATION_CLASS_DFLT;
01118 if (statspec != NULL && statspec->name != 0) {
01119 if (HasBit(statspec->callback_mask, CBM_STATION_AVAIL) && GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) {
01120 GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->line_height - 2, 0, FILLRECT_CHECKER);
01121 }
01122 str = statspec->name;
01123 }
01124 DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, str, i == _railstation.station_type ? TC_WHITE : TC_BLACK);
01125
01126 y += this->line_height;
01127 }
01128 break;
01129 }
01130 }
01131 }
01132
01133 virtual void SetStringParameters(int widget) const
01134 {
01135 if (widget == BRSW_NEWST_DROPDOWN) SetDParam(0, StationClass::GetName(_railstation.station_class));
01136 }
01137
01138 virtual void OnClick(Point pt, int widget, int click_count)
01139 {
01140 switch (widget) {
01141 case BRSW_PLATFORM_DIR_X:
01142 case BRSW_PLATFORM_DIR_Y:
01143 this->RaiseWidget(_railstation.orientation + BRSW_PLATFORM_DIR_X);
01144 _railstation.orientation = (Axis)(widget - BRSW_PLATFORM_DIR_X);
01145 this->LowerWidget(_railstation.orientation + BRSW_PLATFORM_DIR_X);
01146 SndPlayFx(SND_15_BEEP);
01147 this->SetDirty();
01148 DeleteWindowById(WC_SELECT_STATION, 0);
01149 break;
01150
01151 case BRSW_PLATFORM_NUM_1:
01152 case BRSW_PLATFORM_NUM_2:
01153 case BRSW_PLATFORM_NUM_3:
01154 case BRSW_PLATFORM_NUM_4:
01155 case BRSW_PLATFORM_NUM_5:
01156 case BRSW_PLATFORM_NUM_6:
01157 case BRSW_PLATFORM_NUM_7: {
01158 this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
01159 this->RaiseWidget(BRSW_PLATFORM_DRAG_N_DROP);
01160
01161 _settings_client.gui.station_numtracks = widget - BRSW_PLATFORM_NUM_BEGIN;
01162 _settings_client.gui.station_dragdrop = false;
01163
01164 _settings_client.gui.station_dragdrop = false;
01165
01166 const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class, _railstation.station_type) : NULL;
01167 if (statspec != NULL && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
01168
01169 for (uint i = 0; i < 7; i++) {
01170 if (!HasBit(statspec->disallowed_lengths, i)) {
01171 this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
01172 _settings_client.gui.station_platlength = i + 1;
01173 break;
01174 }
01175 }
01176 }
01177
01178 this->LowerWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
01179 this->LowerWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
01180 SndPlayFx(SND_15_BEEP);
01181 this->SetDirty();
01182 DeleteWindowById(WC_SELECT_STATION, 0);
01183 break;
01184 }
01185
01186 case BRSW_PLATFORM_LEN_1:
01187 case BRSW_PLATFORM_LEN_2:
01188 case BRSW_PLATFORM_LEN_3:
01189 case BRSW_PLATFORM_LEN_4:
01190 case BRSW_PLATFORM_LEN_5:
01191 case BRSW_PLATFORM_LEN_6:
01192 case BRSW_PLATFORM_LEN_7: {
01193 this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
01194 this->RaiseWidget(BRSW_PLATFORM_DRAG_N_DROP);
01195
01196 _settings_client.gui.station_platlength = widget - BRSW_PLATFORM_LEN_BEGIN;
01197 _settings_client.gui.station_dragdrop = false;
01198
01199 _settings_client.gui.station_dragdrop = false;
01200
01201 const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class, _railstation.station_type) : NULL;
01202 if (statspec != NULL && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
01203
01204 for (uint i = 0; i < 7; i++) {
01205 if (!HasBit(statspec->disallowed_platforms, i)) {
01206 this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
01207 _settings_client.gui.station_numtracks = i + 1;
01208 break;
01209 }
01210 }
01211 }
01212
01213 this->LowerWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
01214 this->LowerWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
01215 SndPlayFx(SND_15_BEEP);
01216 this->SetDirty();
01217 DeleteWindowById(WC_SELECT_STATION, 0);
01218 break;
01219 }
01220
01221 case BRSW_PLATFORM_DRAG_N_DROP: {
01222 _settings_client.gui.station_dragdrop ^= true;
01223
01224 this->ToggleWidgetLoweredState(BRSW_PLATFORM_DRAG_N_DROP);
01225
01226
01227 const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class, _railstation.station_type) : NULL;
01228 if (statspec != NULL && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
01229 for (uint i = 0; i < 7; i++) {
01230 if (!HasBit(statspec->disallowed_lengths, i)) {
01231 this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
01232 _settings_client.gui.station_platlength = i + 1;
01233 break;
01234 }
01235 }
01236 }
01237 if (statspec != NULL && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
01238 for (uint i = 0; i < 7; i++) {
01239 if (!HasBit(statspec->disallowed_platforms, i)) {
01240 this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
01241 _settings_client.gui.station_numtracks = i + 1;
01242 break;
01243 }
01244 }
01245 }
01246
01247 this->SetWidgetLoweredState(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN, !_settings_client.gui.station_dragdrop);
01248 this->SetWidgetLoweredState(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN, !_settings_client.gui.station_dragdrop);
01249 SndPlayFx(SND_15_BEEP);
01250 this->SetDirty();
01251 DeleteWindowById(WC_SELECT_STATION, 0);
01252 break;
01253 }
01254
01255 case BRSW_HIGHLIGHT_OFF:
01256 case BRSW_HIGHLIGHT_ON:
01257 _settings_client.gui.station_show_coverage = (widget != BRSW_HIGHLIGHT_OFF);
01258
01259 this->SetWidgetLoweredState(BRSW_HIGHLIGHT_OFF, !_settings_client.gui.station_show_coverage);
01260 this->SetWidgetLoweredState(BRSW_HIGHLIGHT_ON, _settings_client.gui.station_show_coverage);
01261 SndPlayFx(SND_15_BEEP);
01262 this->SetDirty();
01263 break;
01264
01265 case BRSW_NEWST_DROPDOWN:
01266 ShowDropDownList(this, BuildStationClassDropDown(), _railstation.station_class, BRSW_NEWST_DROPDOWN);
01267 break;
01268
01269 case BRSW_NEWST_LIST: {
01270 int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, BRSW_NEWST_LIST, 0, this->line_height);
01271 if (y >= _railstation.station_count) return;
01272
01273
01274 const StationSpec *statspec = StationClass::Get(_railstation.station_class, y);
01275 if (statspec != NULL && HasBit(statspec->callback_mask, CBM_STATION_AVAIL) &&
01276 GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) return;
01277
01278 _railstation.station_type = y;
01279
01280 this->CheckSelectedSize(statspec);
01281
01282 SndPlayFx(SND_15_BEEP);
01283 this->SetDirty();
01284 DeleteWindowById(WC_SELECT_STATION, 0);
01285 break;
01286 }
01287 }
01288 }
01289
01290 virtual void OnDropdownSelect(int widget, int index)
01291 {
01292 if (_railstation.station_class != index) {
01293 _railstation.station_class = (StationClassID)index;
01294 _railstation.station_type = 0;
01295 _railstation.station_count = StationClass::GetCount(_railstation.station_class);
01296
01297 this->CheckSelectedSize(StationClass::Get(_railstation.station_class, _railstation.station_type));
01298
01299 this->vscroll->SetCount(_railstation.station_count);
01300 this->vscroll->SetPosition(_railstation.station_type);
01301 }
01302
01303 SndPlayFx(SND_15_BEEP);
01304 this->SetDirty();
01305 DeleteWindowById(WC_SELECT_STATION, 0);
01306 }
01307
01308 virtual void OnTick()
01309 {
01310 CheckRedrawStationCoverage(this);
01311 }
01312 };
01313
01314 static const NWidgetPart _nested_station_builder_widgets[] = {
01315 NWidget(NWID_HORIZONTAL),
01316 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
01317 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_RAIL_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
01318 EndContainer(),
01319 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BRSW_BACKGROUND),
01320
01321 NWidget(NWID_SELECTION, INVALID_COLOUR, BRSW_SHOW_NEWST_ADDITIONS),
01322 NWidget(NWID_VERTICAL),
01323 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),
01324 NWidget(NWID_HORIZONTAL), SetPIP(7, 0, 7),
01325 NWidget(WWT_MATRIX, COLOUR_GREY, BRSW_NEWST_LIST), SetMinimalSize(122, 71), SetFill(1, 0), SetDataTip(0x501, STR_STATION_BUILD_STATION_TYPE_TOOLTIP), SetScrollbar(BRSW_NEWST_SCROLL),
01326 NWidget(NWID_VSCROLLBAR, COLOUR_GREY, BRSW_NEWST_SCROLL),
01327 EndContainer(),
01328 NWidget(NWID_SPACER), SetMinimalSize(0, 1),
01329 EndContainer(),
01330 EndContainer(),
01331
01332 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_ORIENTATION, STR_NULL), SetPadding(1, 2, 0, 2),
01333 NWidget(NWID_HORIZONTAL),
01334 NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0),
01335 NWidget(WWT_PANEL, COLOUR_GREY, BRSW_PLATFORM_DIR_X), SetMinimalSize(66, 48), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(),
01336 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01337 NWidget(WWT_PANEL, COLOUR_GREY, BRSW_PLATFORM_DIR_Y), SetMinimalSize(66, 48), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(),
01338 NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0),
01339 EndContainer(),
01340 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_NUMBER_OF_TRACKS, STR_NULL), SetPadding(2, 2, 0, 2),
01341 NWidget(NWID_HORIZONTAL),
01342 NWidget(NWID_SPACER), SetFill(1, 0),
01343 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_1), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_1, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01344 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_2), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_2, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01345 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_3), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_3, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01346 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_4), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_4, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01347 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_5), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_5, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01348 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_6), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_6, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01349 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_7), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_7, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01350 NWidget(NWID_SPACER), SetFill(1, 0),
01351 EndContainer(),
01352 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_PLATFORM_LENGTH, STR_NULL), SetPadding(2, 2, 0, 2),
01353 NWidget(NWID_HORIZONTAL),
01354 NWidget(NWID_SPACER), SetFill(1, 0),
01355 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_1), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_1, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01356 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_2), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_2, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01357 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_3), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_3, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01358 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_4), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_4, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01359 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_5), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_5, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01360 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_6), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_6, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01361 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_7), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_7, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01362 NWidget(NWID_SPACER), SetFill(1, 0),
01363 EndContainer(),
01364 NWidget(NWID_SPACER), SetMinimalSize(0, 2),
01365 NWidget(NWID_HORIZONTAL),
01366 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01367 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),
01368 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01369 EndContainer(),
01370 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetPadding(3, 2, 0, 2),
01371 NWidget(NWID_HORIZONTAL),
01372 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01373 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_HIGHLIGHT_OFF), SetMinimalSize(60, 12),
01374 SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
01375 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_HIGHLIGHT_ON), SetMinimalSize(60, 12),
01376 SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
01377 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01378 EndContainer(),
01379 NWidget(NWID_SPACER), SetMinimalSize(0, 20), SetResize(0, 1),
01380 EndContainer(),
01381 };
01382
01384 static const WindowDesc _station_builder_desc(
01385 WDP_AUTO, 0, 0,
01386 WC_BUILD_STATION, WC_BUILD_TOOLBAR,
01387 WDF_CONSTRUCTION,
01388 _nested_station_builder_widgets, lengthof(_nested_station_builder_widgets)
01389 );
01390
01392 static void ShowStationBuilder(Window *parent)
01393 {
01394 bool newstations = StationClass::GetCount() > 2 || StationClass::GetCount(STAT_CLASS_DFLT) != 1;
01395 new BuildRailStationWindow(&_station_builder_desc, parent, newstations);
01396 }
01397
01399 enum BuildSignalWidgets {
01400 BSW_SEMAPHORE_NORM,
01401 BSW_SEMAPHORE_ENTRY,
01402 BSW_SEMAPHORE_EXIT,
01403 BSW_SEMAPHORE_COMBO,
01404 BSW_SEMAPHORE_PBS,
01405 BSW_SEMAPHORE_PBS_OWAY,
01406 BSW_ELECTRIC_NORM,
01407 BSW_ELECTRIC_ENTRY,
01408 BSW_ELECTRIC_EXIT,
01409 BSW_ELECTRIC_COMBO,
01410 BSW_ELECTRIC_PBS,
01411 BSW_ELECTRIC_PBS_OWAY,
01412 BSW_CONVERT,
01413 BSW_DRAG_SIGNALS_DENSITY,
01414 BSW_DRAG_SIGNALS_DENSITY_LABEL,
01415 BSW_DRAG_SIGNALS_DENSITY_DECREASE,
01416 BSW_DRAG_SIGNALS_DENSITY_INCREASE,
01417 };
01418
01419 struct BuildSignalWindow : public PickerWindowBase {
01420 private:
01428 void DrawSignalSprite(byte widget_index, SpriteID image) const
01429 {
01430
01431 image += this->IsWidgetLowered(widget_index);
01432
01433
01434 const Sprite *sprite = GetSprite(image, ST_NORMAL);
01435
01436
01437
01438
01439
01440 int sprite_center_x_offset = sprite->x_offs + sprite->width / 2;
01441 int sprite_bottom_y_offset = sprite->height + sprite->y_offs;
01442
01443
01444
01445 const NWidgetBase *widget = this->GetWidget<NWidgetBase>(widget_index);
01446 int widget_center_x = widget->pos_x + widget->current_x / 2;
01447 int widget_bottom_y = widget->pos_y + widget->current_y - 2;
01448
01449
01450 DrawSprite(image, PAL_NONE,
01451 widget_center_x - sprite_center_x_offset + this->IsWidgetLowered(widget_index),
01452 widget_bottom_y - sprite_bottom_y_offset + this->IsWidgetLowered(widget_index));
01453 }
01454
01455 public:
01456 BuildSignalWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(parent)
01457 {
01458 this->InitNested(desc, TRANSPORT_RAIL);
01459 this->OnInvalidateData();
01460 };
01461
01462 virtual void SetStringParameters(int widget) const
01463 {
01464 switch (widget) {
01465 case BSW_DRAG_SIGNALS_DENSITY_LABEL:
01466 SetDParam(0, _settings_client.gui.drag_signals_density);
01467 break;
01468 }
01469 }
01470
01471 virtual void DrawWidget(const Rect &r, int widget) const
01472 {
01473 if (IsInsideMM(widget, BSW_SEMAPHORE_NORM, BSW_ELECTRIC_PBS_OWAY + 1)) {
01474
01475 const SpriteID _signal_lookup[] = {
01476 SPR_IMG_SIGNAL_SEMAPHORE_NORM, SPR_IMG_SIGNAL_SEMAPHORE_ENTRY, SPR_IMG_SIGNAL_SEMAPHORE_EXIT,
01477 SPR_IMG_SIGNAL_SEMAPHORE_COMBO, SPR_IMG_SIGNAL_SEMAPHORE_PBS, SPR_IMG_SIGNAL_SEMAPHORE_PBS_OWAY,
01478
01479 SPR_IMG_SIGNAL_ELECTRIC_NORM, SPR_IMG_SIGNAL_ELECTRIC_ENTRY, SPR_IMG_SIGNAL_ELECTRIC_EXIT,
01480 SPR_IMG_SIGNAL_ELECTRIC_COMBO, SPR_IMG_SIGNAL_ELECTRIC_PBS, SPR_IMG_SIGNAL_ELECTRIC_PBS_OWAY
01481 };
01482
01483 this->DrawSignalSprite(widget, _signal_lookup[widget - BSW_SEMAPHORE_NORM]);
01484 }
01485 }
01486
01487 virtual void OnClick(Point pt, int widget, int click_count)
01488 {
01489 switch (widget) {
01490 case BSW_SEMAPHORE_NORM:
01491 case BSW_SEMAPHORE_ENTRY:
01492 case BSW_SEMAPHORE_EXIT:
01493 case BSW_SEMAPHORE_COMBO:
01494 case BSW_SEMAPHORE_PBS:
01495 case BSW_SEMAPHORE_PBS_OWAY:
01496 case BSW_ELECTRIC_NORM:
01497 case BSW_ELECTRIC_ENTRY:
01498 case BSW_ELECTRIC_EXIT:
01499 case BSW_ELECTRIC_COMBO:
01500 case BSW_ELECTRIC_PBS:
01501 case BSW_ELECTRIC_PBS_OWAY:
01502 this->RaiseWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type);
01503
01504 _cur_signal_type = (SignalType)((uint)((widget - BSW_SEMAPHORE_NORM) % (SIGTYPE_LAST + 1)));
01505 _cur_signal_variant = widget >= BSW_ELECTRIC_NORM ? SIG_ELECTRIC : SIG_SEMAPHORE;
01506 break;
01507
01508 case BSW_CONVERT:
01509 _convert_signal_button = !_convert_signal_button;
01510 break;
01511
01512 case BSW_DRAG_SIGNALS_DENSITY_DECREASE:
01513 if (_settings_client.gui.drag_signals_density > 1) {
01514 _settings_client.gui.drag_signals_density--;
01515 SetWindowDirty(WC_GAME_OPTIONS, 0);
01516 }
01517 break;
01518
01519 case BSW_DRAG_SIGNALS_DENSITY_INCREASE:
01520 if (_settings_client.gui.drag_signals_density < 20) {
01521 _settings_client.gui.drag_signals_density++;
01522 SetWindowDirty(WC_GAME_OPTIONS, 0);
01523 }
01524 break;
01525
01526 default: break;
01527 }
01528
01529 this->InvalidateData();
01530 }
01531
01532 virtual void OnInvalidateData(int data = 0)
01533 {
01534 this->LowerWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type);
01535
01536 this->SetWidgetLoweredState(BSW_CONVERT, _convert_signal_button);
01537
01538 this->SetWidgetDisabledState(BSW_DRAG_SIGNALS_DENSITY_DECREASE, _settings_client.gui.drag_signals_density == 1);
01539 this->SetWidgetDisabledState(BSW_DRAG_SIGNALS_DENSITY_INCREASE, _settings_client.gui.drag_signals_density == 20);
01540 }
01541 };
01542
01544 static const NWidgetPart _nested_signal_builder_widgets[] = {
01545 NWidget(NWID_HORIZONTAL),
01546 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
01547 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_BUILD_SIGNAL_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
01548 EndContainer(),
01549 NWidget(NWID_VERTICAL, NC_EQUALSIZE),
01550 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
01551 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_NORM), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP), EndContainer(), SetFill(1, 1),
01552 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_ENTRY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP), EndContainer(), SetFill(1, 1),
01553 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_EXIT), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP), EndContainer(), SetFill(1, 1),
01554 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_COMBO), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP), EndContainer(), SetFill(1, 1),
01555 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_PBS), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP), EndContainer(), SetFill(1, 1),
01556 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_PBS_OWAY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP), EndContainer(), SetFill(1, 1),
01557 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, BSW_CONVERT), SetDataTip(SPR_IMG_SIGNAL_CONVERT, STR_BUILD_SIGNAL_CONVERT_TOOLTIP), SetFill(1, 1),
01558 EndContainer(),
01559 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
01560 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_NORM), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP), EndContainer(), SetFill(1, 1),
01561 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_ENTRY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TOOLTIP), EndContainer(), SetFill(1, 1),
01562 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_EXIT), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP), EndContainer(), SetFill(1, 1),
01563 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_COMBO), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP), EndContainer(), SetFill(1, 1),
01564 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_PBS), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP), EndContainer(), SetFill(1, 1),
01565 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_PBS_OWAY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP), EndContainer(), SetFill(1, 1),
01566 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_DRAG_SIGNALS_DENSITY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(1, 1),
01567 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),
01568 NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
01569 NWidget(NWID_SPACER), SetFill(1, 0),
01570 NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, BSW_DRAG_SIGNALS_DENSITY_DECREASE), SetMinimalSize(9, 12), SetDataTip(AWV_DECREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP),
01571 NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, BSW_DRAG_SIGNALS_DENSITY_INCREASE), SetMinimalSize(9, 12), SetDataTip(AWV_INCREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP),
01572 NWidget(NWID_SPACER), SetFill(1, 0),
01573 EndContainer(),
01574 NWidget(NWID_SPACER), SetMinimalSize(0, 2), SetFill(1, 0),
01575 EndContainer(),
01576 EndContainer(),
01577 EndContainer(),
01578 };
01579
01581 static const WindowDesc _signal_builder_desc(
01582 WDP_AUTO, 0, 0,
01583 WC_BUILD_SIGNAL, WC_BUILD_TOOLBAR,
01584 WDF_UNCLICK_BUTTONS | WDF_CONSTRUCTION,
01585 _nested_signal_builder_widgets, lengthof(_nested_signal_builder_widgets)
01586 );
01587
01591 static void ShowSignalBuilder(Window *parent)
01592 {
01593 new BuildSignalWindow(&_signal_builder_desc, parent);
01594 }
01595
01597 enum BuildRailDepotWidgets {
01598 BRDW_DEPOT_NE,
01599 BRDW_DEPOT_SE,
01600 BRDW_DEPOT_SW,
01601 BRDW_DEPOT_NW,
01602 };
01603
01604 struct BuildRailDepotWindow : public PickerWindowBase {
01605 BuildRailDepotWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(parent)
01606 {
01607 this->InitNested(desc, TRANSPORT_RAIL);
01608 this->LowerWidget(_build_depot_direction + BRDW_DEPOT_NE);
01609 }
01610
01611 virtual void DrawWidget(const Rect &r, int widget) const
01612 {
01613 if (!IsInsideMM(widget, BRDW_DEPOT_NE, BRDW_DEPOT_NW + 1)) return;
01614
01615 DrawTrainDepotSprite(r.left - 1, r.top, widget - BRDW_DEPOT_NE + DIAGDIR_NE, _cur_railtype);
01616 }
01617
01618 virtual void OnClick(Point pt, int widget, int click_count)
01619 {
01620 switch (widget) {
01621 case BRDW_DEPOT_NE:
01622 case BRDW_DEPOT_SE:
01623 case BRDW_DEPOT_SW:
01624 case BRDW_DEPOT_NW:
01625 this->RaiseWidget(_build_depot_direction + BRDW_DEPOT_NE);
01626 _build_depot_direction = (DiagDirection)(widget - BRDW_DEPOT_NE);
01627 this->LowerWidget(_build_depot_direction + BRDW_DEPOT_NE);
01628 SndPlayFx(SND_15_BEEP);
01629 this->SetDirty();
01630 break;
01631 }
01632 }
01633 };
01634
01636 static const NWidgetPart _nested_build_depot_widgets[] = {
01637 NWidget(NWID_HORIZONTAL),
01638 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
01639 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_BUILD_DEPOT_TRAIN_ORIENTATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
01640 EndContainer(),
01641 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
01642 NWidget(NWID_SPACER), SetMinimalSize(0, 3),
01643 NWidget(NWID_HORIZONTAL_LTR),
01644 NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
01645 NWidget(NWID_VERTICAL),
01646 NWidget(WWT_PANEL, COLOUR_GREY, BRDW_DEPOT_NW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
01647 EndContainer(),
01648 NWidget(NWID_SPACER), SetMinimalSize(0, 2),
01649 NWidget(WWT_PANEL, COLOUR_GREY, BRDW_DEPOT_SW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
01650 EndContainer(),
01651 EndContainer(),
01652 NWidget(NWID_SPACER), SetMinimalSize(2, 0),
01653 NWidget(NWID_VERTICAL),
01654 NWidget(WWT_PANEL, COLOUR_GREY, BRDW_DEPOT_NE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
01655 EndContainer(),
01656 NWidget(NWID_SPACER), SetMinimalSize(0, 2),
01657 NWidget(WWT_PANEL, COLOUR_GREY, BRDW_DEPOT_SE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
01658 EndContainer(),
01659 EndContainer(),
01660 NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
01661 EndContainer(),
01662 NWidget(NWID_SPACER), SetMinimalSize(0, 3),
01663 EndContainer(),
01664 };
01665
01666 static const WindowDesc _build_depot_desc(
01667 WDP_AUTO, 0, 0,
01668 WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
01669 WDF_CONSTRUCTION,
01670 _nested_build_depot_widgets, lengthof(_nested_build_depot_widgets)
01671 );
01672
01673 static void ShowBuildTrainDepotPicker(Window *parent)
01674 {
01675 new BuildRailDepotWindow(&_build_depot_desc, parent);
01676 }
01677
01679 enum BuildRailWaypointWidgets {
01680 BRWW_WAYPOINT_MATRIX,
01681 BRWW_WAYPOINT,
01682 BRWW_SCROLL,
01683 };
01684
01685 struct BuildRailWaypointWindow : PickerWindowBase {
01686 BuildRailWaypointWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(parent)
01687 {
01688 this->CreateNestedTree(desc);
01689
01690 NWidgetMatrix *matrix = this->GetWidget<NWidgetMatrix>(BRWW_WAYPOINT_MATRIX);
01691 matrix->SetScrollbar(this->GetScrollbar(BRWW_SCROLL));
01692
01693 this->FinishInitNested(desc, TRANSPORT_RAIL);
01694
01695 matrix->SetCount(_waypoint_count);
01696 matrix->SetClicked(_cur_waypoint_type);
01697 };
01698
01699 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
01700 {
01701 switch (widget) {
01702 case BRWW_WAYPOINT_MATRIX:
01703
01704 size->width += resize->width * 2;
01705 size->height += resize->height * 2;
01706
01707
01708 resize->height = 1;
01709 break;
01710 }
01711 }
01712
01713 virtual void DrawWidget(const Rect &r, int widget) const
01714 {
01715 switch (GB(widget, 0, 16)) {
01716 case BRWW_WAYPOINT: {
01717 byte type = GB(widget, 16, 16);
01718 const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP, type);
01719 DrawWaypointSprite(r.left + TILE_PIXELS, r.bottom - TILE_PIXELS, type, _cur_railtype);
01720
01721 if (statspec != NULL &&
01722 HasBit(statspec->callback_mask, CBM_STATION_AVAIL) &&
01723 GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) {
01724 GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, 0, FILLRECT_CHECKER);
01725 }
01726 }
01727 }
01728 }
01729
01730 virtual void OnClick(Point pt, int widget, int click_count)
01731 {
01732 switch (GB(widget, 0, 16)) {
01733 case BRWW_WAYPOINT: {
01734 byte type = GB(widget, 16, 16);
01735 this->GetWidget<NWidgetMatrix>(BRWW_WAYPOINT_MATRIX)->SetClicked(_cur_waypoint_type);
01736
01737
01738 const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP, type);
01739 if (statspec != NULL &&
01740 HasBit(statspec->callback_mask, CBM_STATION_AVAIL) &&
01741 GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) return;
01742
01743 _cur_waypoint_type = type;
01744 this->GetWidget<NWidgetMatrix>(BRWW_WAYPOINT_MATRIX)->SetClicked(_cur_waypoint_type);
01745 SndPlayFx(SND_15_BEEP);
01746 this->SetDirty();
01747 break;
01748 }
01749 }
01750 }
01751 };
01752
01754 static const NWidgetPart _nested_build_waypoint_widgets[] = {
01755 NWidget(NWID_HORIZONTAL),
01756 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
01757 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_WAYPOINT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
01758 EndContainer(),
01759 NWidget(NWID_HORIZONTAL),
01760 NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, BRWW_WAYPOINT_MATRIX), SetPIP(3, 2, 3), SetScrollbar(BRWW_SCROLL),
01761 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BRWW_WAYPOINT), SetMinimalSize(66, 60), SetDataTip(0x0, STR_WAYPOINT_GRAPHICS_TOOLTIP), EndContainer(),
01762 EndContainer(),
01763 NWidget(NWID_VERTICAL),
01764 NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, BRWW_SCROLL),
01765 NWidget(WWT_RESIZEBOX, COLOUR_DARK_GREEN),
01766 EndContainer(),
01767 EndContainer(),
01768 };
01769
01770 static const WindowDesc _build_waypoint_desc(
01771 WDP_AUTO, 0, 0,
01772 WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
01773 WDF_CONSTRUCTION,
01774 _nested_build_waypoint_widgets, lengthof(_nested_build_waypoint_widgets)
01775 );
01776
01777 static void ShowBuildWaypointPicker(Window *parent)
01778 {
01779 new BuildRailWaypointWindow(&_build_waypoint_desc, parent);
01780 }
01781
01785 void InitializeRailGui()
01786 {
01787 _build_depot_direction = DIAGDIR_NW;
01788 }
01789
01794 void ReinitGuiAfterToggleElrail(bool disable)
01795 {
01796 extern RailType _last_built_railtype;
01797 if (disable && _last_built_railtype == RAILTYPE_ELECTRIC) {
01798 _last_built_railtype = _cur_railtype = RAILTYPE_RAIL;
01799 BuildRailToolbarWindow *w = dynamic_cast<BuildRailToolbarWindow *>(FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_RAIL));
01800 if (w != NULL) w->ModifyRailType(_cur_railtype);
01801 }
01802 MarkWholeScreenDirty();
01803 }
01804
01806 static void SetDefaultRailGui()
01807 {
01808 if (_local_company == COMPANY_SPECTATOR || !Company::IsValidID(_local_company)) return;
01809
01810 extern RailType _last_built_railtype;
01811 RailType rt = (RailType)(_settings_client.gui.default_rail_type + RAILTYPE_END);
01812 if (rt == DEF_RAILTYPE_MOST_USED) {
01813
01814 RailType count[RAILTYPE_END];
01815 memset(count, 0, sizeof(count));
01816 for (TileIndex t = 0; t < MapSize(); t++) {
01817 if (IsTileType(t, MP_RAILWAY) || IsLevelCrossingTile(t) || HasStationTileRail(t) ||
01818 (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL)) {
01819 count[GetRailType(t)]++;
01820 }
01821 }
01822
01823 rt = RAILTYPE_RAIL;
01824 for (RailType r = RAILTYPE_ELECTRIC; r < RAILTYPE_END; r++) {
01825 if (count[r] >= count[rt]) rt = r;
01826 }
01827
01828
01829 if (count[rt] == 0) rt = DEF_RAILTYPE_FIRST;
01830 }
01831 switch (rt) {
01832 case DEF_RAILTYPE_FIRST:
01833 rt = RAILTYPE_RAIL;
01834 while (rt < RAILTYPE_END && !HasRailtypeAvail(_local_company, rt)) rt++;
01835 break;
01836
01837 case DEF_RAILTYPE_LAST:
01838 rt = GetBestRailtype(_local_company);
01839 break;
01840
01841 default:
01842 break;
01843 }
01844
01845 _last_built_railtype = _cur_railtype = rt;
01846 BuildRailToolbarWindow *w = dynamic_cast<BuildRailToolbarWindow *>(FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_RAIL));
01847 if (w != NULL) w->ModifyRailType(_cur_railtype);
01848 }
01849
01856 bool ResetSignalVariant(int32 p = 0)
01857 {
01858 SignalVariant new_variant = (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC);
01859
01860 if (new_variant != _cur_signal_variant) {
01861 Window *w = FindWindowById(WC_BUILD_SIGNAL, 0);
01862 if (w != NULL) {
01863 w->SetDirty();
01864 w->RaiseWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type);
01865 }
01866 _cur_signal_variant = new_variant;
01867 }
01868
01869 return true;
01870 }
01871
01876 void InitializeRailGUI()
01877 {
01878 SetDefaultRailGui();
01879
01880 _convert_signal_button = false;
01881 _cur_signal_type = _default_signal_type[_settings_client.gui.default_signal_type];
01882 ResetSignalVariant();
01883 }