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