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 #include "engine_base.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 extern RailType _last_built_railtype;
00854 int num = CheckHotkeyMatch<BuildRailToolbarWindow>(_railtoolbar_hotkeys, keycode, NULL, true);
00855 if (num == -1) return ES_NOT_HANDLED;
00856 Window *w = ShowBuildRailToolbar(_last_built_railtype);
00857 if (w == NULL) return ES_NOT_HANDLED;
00858 return w->OnKeyPress(key, keycode);
00859 }
00860
00861
00862
00863
00864 static void HandleStationPlacement(TileIndex start, TileIndex end)
00865 {
00866 TileArea ta(start, end);
00867 uint numtracks = ta.w;
00868 uint platlength = ta.h;
00869
00870 if (_railstation.orientation == AXIS_X) Swap(numtracks, platlength);
00871
00872 uint32 p1 = _cur_railtype | _railstation.orientation << 4 | numtracks << 8 | platlength << 16 | _ctrl_pressed << 24;
00873 uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16;
00874
00875 CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" };
00876 ShowSelectStationIfNeeded(cmdcont, ta);
00877 }
00878
00880 enum BuildRailStationWidgets {
00881 BRSW_PLATFORM_DIR_X,
00882 BRSW_PLATFORM_DIR_Y,
00883
00884 BRSW_PLATFORM_NUM_1,
00885 BRSW_PLATFORM_NUM_2,
00886 BRSW_PLATFORM_NUM_3,
00887 BRSW_PLATFORM_NUM_4,
00888 BRSW_PLATFORM_NUM_5,
00889 BRSW_PLATFORM_NUM_6,
00890 BRSW_PLATFORM_NUM_7,
00891
00892 BRSW_PLATFORM_LEN_1,
00893 BRSW_PLATFORM_LEN_2,
00894 BRSW_PLATFORM_LEN_3,
00895 BRSW_PLATFORM_LEN_4,
00896 BRSW_PLATFORM_LEN_5,
00897 BRSW_PLATFORM_LEN_6,
00898 BRSW_PLATFORM_LEN_7,
00899
00900 BRSW_PLATFORM_DRAG_N_DROP,
00901
00902 BRSW_HIGHLIGHT_OFF,
00903 BRSW_HIGHLIGHT_ON,
00904 BRSW_COVERAGE_TEXTS,
00905
00906 BRSW_MATRIX,
00907 BRSW_IMAGE,
00908 BRSW_MATRIX_SCROLL,
00909
00910 BRSW_SHOW_NEWST_ADDITIONS,
00911 BRSW_SHOW_NEWST_MATRIX,
00912 BRSW_SHOW_NEWST_RESIZE,
00913 BRSW_SHOW_NEWST_TYPE,
00914 BRSW_NEWST_LIST,
00915 BRSW_NEWST_SCROLL,
00916
00917 BRSW_PLATFORM_NUM_BEGIN = BRSW_PLATFORM_NUM_1 - 1,
00918 BRSW_PLATFORM_LEN_BEGIN = BRSW_PLATFORM_LEN_1 - 1,
00919 };
00920
00921 struct BuildRailStationWindow : public PickerWindowBase {
00922 private:
00923 uint line_height;
00924 uint coverage_height;
00925 Scrollbar *vscroll;
00926 Scrollbar *vscroll2;
00927
00933 void CheckSelectedSize(const StationSpec *statspec)
00934 {
00935 if (statspec == NULL || _settings_client.gui.station_dragdrop) return;
00936
00937
00938 if (HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
00939 this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
00940 _settings_client.gui.station_numtracks = 1;
00941 while (HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
00942 _settings_client.gui.station_numtracks++;
00943 }
00944 this->LowerWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
00945 }
00946
00947 if (HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
00948 this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
00949 _settings_client.gui.station_platlength = 1;
00950 while (HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
00951 _settings_client.gui.station_platlength++;
00952 }
00953 this->LowerWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
00954 }
00955 }
00956
00957 public:
00958 BuildRailStationWindow(const WindowDesc *desc, Window *parent, bool newstation) : PickerWindowBase(parent)
00959 {
00960 this->coverage_height = 2 * FONT_HEIGHT_NORMAL + 3 * WD_PAR_VSEP_NORMAL;
00961 this->vscroll = NULL;
00962 _railstation.newstations = newstation;
00963
00964 this->CreateNestedTree(desc);
00965 NWidgetStacked *newst_additions = this->GetWidget<NWidgetStacked>(BRSW_SHOW_NEWST_ADDITIONS);
00966 newst_additions->SetDisplayedPlane(newstation ? 0 : SZSP_NONE);
00967 newst_additions = this->GetWidget<NWidgetStacked>(BRSW_SHOW_NEWST_MATRIX);
00968 newst_additions->SetDisplayedPlane(newstation ? 0 : SZSP_NONE);
00969 newst_additions = this->GetWidget<NWidgetStacked>(BRSW_SHOW_NEWST_RESIZE);
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 if (!newstation || _railstation.station_class >= (int)StationClass::GetCount()) {
00984
00985
00986 _railstation.station_class = STAT_CLASS_DFLT;
00987 _railstation.station_type = 0;
00988 this->vscroll2 = NULL;
00989 }
00990 if (newstation) {
00991 _railstation.station_count = StationClass::GetCount(_railstation.station_class);
00992 _railstation.station_type = min(_railstation.station_type, _railstation.station_count - 1);
00993
00994 int count = 0;
00995 for (uint i = 0; i < StationClass::GetCount(); i++) {
00996 if (i == STAT_CLASS_WAYP) continue;
00997 count++;
00998 }
00999 this->vscroll = this->GetScrollbar(BRSW_NEWST_SCROLL);
01000 this->vscroll->SetCount(count);
01001 this->vscroll->SetCapacity(GB(this->GetWidget<NWidgetCore>(BRSW_NEWST_LIST)->widget_data, MAT_ROW_START, MAT_ROW_BITS));
01002 this->vscroll->SetPosition(Clamp(_railstation.station_class - 2, 0, max(this->vscroll->GetCount() - this->vscroll->GetCapacity(), 0)));
01003
01004 this->vscroll2 = this->GetScrollbar(BRSW_MATRIX_SCROLL);
01005 NWidgetMatrix *matrix = this->GetWidget<NWidgetMatrix>(BRSW_MATRIX);
01006 matrix->SetScrollbar(this->vscroll2);
01007 matrix->SetCount(_railstation.station_count);
01008 matrix->SetClicked(0);
01009 }
01010 }
01011
01012 virtual ~BuildRailStationWindow()
01013 {
01014 DeleteWindowById(WC_SELECT_STATION, 0);
01015 }
01016
01017 virtual void OnPaint()
01018 {
01019 bool newstations = _railstation.newstations;
01020 const StationSpec *statspec = newstations ? StationClass::Get(_railstation.station_class, _railstation.station_type) : NULL;
01021
01022 if (_settings_client.gui.station_dragdrop) {
01023 SetTileSelectSize(1, 1);
01024 } else {
01025 int x = _settings_client.gui.station_numtracks;
01026 int y = _settings_client.gui.station_platlength;
01027 if (_railstation.orientation == AXIS_X) Swap(x, y);
01028 if (!_remove_button_clicked) {
01029 SetTileSelectSize(x, y);
01030 }
01031 }
01032
01033 int rad = (_settings_game.station.modified_catchment) ? CA_TRAIN : CA_UNMODIFIED;
01034
01035 if (_settings_client.gui.station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
01036
01037 for (uint bits = 0; bits < 7; bits++) {
01038 bool disable = bits >= _settings_game.station.station_spread;
01039 if (statspec == NULL) {
01040 this->SetWidgetDisabledState(bits + BRSW_PLATFORM_NUM_1, disable);
01041 this->SetWidgetDisabledState(bits + BRSW_PLATFORM_LEN_1, disable);
01042 } else {
01043 this->SetWidgetDisabledState(bits + BRSW_PLATFORM_NUM_1, HasBit(statspec->disallowed_platforms, bits) || disable);
01044 this->SetWidgetDisabledState(bits + BRSW_PLATFORM_LEN_1, HasBit(statspec->disallowed_lengths, bits) || disable);
01045 }
01046 }
01047
01048 this->DrawWidgets();
01049
01050
01051 NWidgetBase *cov = this->GetWidget<NWidgetBase>(BRSW_COVERAGE_TEXTS);
01052 int top = cov->pos_y + WD_PAR_VSEP_NORMAL;
01053 int left = cov->pos_x + WD_FRAMERECT_LEFT;
01054 int right = cov->pos_x + cov->current_x - WD_FRAMERECT_RIGHT;
01055 int bottom = cov->pos_y + cov->current_y;
01056 top = DrawStationCoverageAreaText(left, right, top, SCT_ALL, rad, false) + WD_PAR_VSEP_NORMAL;
01057 top = DrawStationCoverageAreaText(left, right, top, SCT_ALL, rad, true) + WD_PAR_VSEP_NORMAL;
01058
01059 if (top != bottom) {
01060 this->coverage_height += top - bottom;
01061 this->ReInit();
01062 }
01063 }
01064
01065 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
01066 {
01067 switch (widget) {
01068 case BRSW_NEWST_LIST: {
01069 Dimension d = {0, 0};
01070 for (uint i = 0; i < StationClass::GetCount(); i++) {
01071 if (i == STAT_CLASS_WAYP) continue;
01072 SetDParam(0, StationClass::GetName((StationClassID)i));
01073 d = maxdim(d, GetStringBoundingBox(STR_BLACK_STRING));
01074 }
01075 size->width = max(size->width, d.width + padding.width);
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 resize->height = this->line_height;
01079 break;
01080 }
01081
01082 case BRSW_SHOW_NEWST_TYPE: {
01083 if (!_railstation.newstations) {
01084 size->width = 0;
01085 size->height = 0;
01086 break;
01087 }
01088
01089
01090 Dimension d = {0, 0};
01091 StringID str = this->GetWidget<NWidgetCore>(widget)->widget_data;
01092 for (StationClassID statclass = STAT_CLASS_BEGIN; statclass < (StationClassID)StationClass::GetCount(); statclass++) {
01093 if (statclass == STAT_CLASS_WAYP) continue;
01094 for (uint16 j = 0; j < StationClass::GetCount(statclass); j++) {
01095 const StationSpec *statspec = StationClass::Get(statclass, j);
01096 SetDParam(0, (statspec != NULL && statspec->name != 0) ? statspec->name : STR_STATION_CLASS_DFLT);
01097 d = maxdim(d, GetStringBoundingBox(str));
01098 }
01099 }
01100 size->width = max(size->width, d.width + padding.width);
01101 break;
01102 }
01103
01104 case BRSW_COVERAGE_TEXTS:
01105 size->height = this->coverage_height;
01106 break;
01107
01108 case BRSW_MATRIX:
01109 fill->height = 1;
01110 resize->height = 1;
01111 break;
01112 }
01113 }
01114
01115 virtual void DrawWidget(const Rect &r, int widget) const
01116 {
01117 DrawPixelInfo tmp_dpi;
01118
01119 switch (GB(widget, 0, 16)) {
01120 case BRSW_PLATFORM_DIR_X:
01121
01122 if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left + 1, r.bottom - r.top + 1)) {
01123 DrawPixelInfo *old_dpi = _cur_dpi;
01124 _cur_dpi = &tmp_dpi;
01125 if (!DrawStationTile(32, 16, _cur_railtype, AXIS_X, _railstation.station_class, _railstation.station_type)) {
01126 StationPickerDrawSprite(32, 16, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2);
01127 }
01128 _cur_dpi = old_dpi;
01129 }
01130 break;
01131
01132 case BRSW_PLATFORM_DIR_Y:
01133
01134 if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left + 1, r.bottom - r.top + 1)) {
01135 DrawPixelInfo *old_dpi = _cur_dpi;
01136 _cur_dpi = &tmp_dpi;
01137 if (!DrawStationTile(32, 16, _cur_railtype, AXIS_Y, _railstation.station_class, _railstation.station_type)) {
01138 StationPickerDrawSprite(32, 16, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 3);
01139 }
01140 _cur_dpi = old_dpi;
01141 }
01142 break;
01143
01144 case BRSW_NEWST_LIST: {
01145 uint statclass = 0;
01146 uint row = 0;
01147 for (uint i = 0; i < StationClass::GetCount(); i++) {
01148 if (i == STAT_CLASS_WAYP) continue;
01149 if (this->vscroll->IsVisible(statclass)) {
01150 SetDParam(0, StationClass::GetName((StationClassID)i));
01151 DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, row * this->line_height + r.top + WD_MATRIX_TOP, STR_JUST_STRING,
01152 (StationClassID)i == _railstation.station_class ? TC_WHITE : TC_BLACK);
01153 row++;
01154 }
01155 statclass++;
01156 }
01157 break;
01158 }
01159
01160 case BRSW_IMAGE: {
01161 byte type = GB(widget, 16, 16);
01162 assert(type < _railstation.station_count);
01163
01164 const StationSpec *statspec = StationClass::Get(_railstation.station_class, type);
01165 if (statspec != NULL && HasBit(statspec->callback_mask, CBM_STATION_AVAIL) &&
01166 GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) {
01167 GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, 0, FILLRECT_CHECKER);
01168 }
01169
01170
01171 if (FillDrawPixelInfo(&tmp_dpi, r.left + 1, r.top + 1, r.right - (r.left + 1) + 1, r.bottom - 1 - (r.top + 1) + 1)) {
01172 DrawPixelInfo *old_dpi = _cur_dpi;
01173 _cur_dpi = &tmp_dpi;
01174 if (!DrawStationTile(31, 29, _cur_railtype, _railstation.orientation, _railstation.station_class, type)) {
01175 StationPickerDrawSprite(31, 29, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2 + _railstation.orientation);
01176 }
01177 _cur_dpi = old_dpi;
01178 }
01179 break;
01180 }
01181 }
01182 }
01183
01184 virtual void OnResize()
01185 {
01186 if (this->vscroll != NULL) {
01187 this->vscroll->SetCapacityFromWidget(this, BRSW_NEWST_LIST);
01188 this->GetWidget<NWidgetCore>(BRSW_NEWST_LIST)->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START);
01189 }
01190 }
01191
01192 virtual void SetStringParameters(int widget) const
01193 {
01194 if (widget == BRSW_SHOW_NEWST_TYPE) {
01195 const StationSpec *statspec = StationClass::Get(_railstation.station_class, _railstation.station_type);
01196 SetDParam(0, (statspec != NULL && statspec->name != 0) ? statspec->name : STR_STATION_CLASS_DFLT);
01197 }
01198 }
01199
01200 virtual void OnClick(Point pt, int widget, int click_count)
01201 {
01202 switch (GB(widget, 0, 16)) {
01203 case BRSW_PLATFORM_DIR_X:
01204 case BRSW_PLATFORM_DIR_Y:
01205 this->RaiseWidget(_railstation.orientation + BRSW_PLATFORM_DIR_X);
01206 _railstation.orientation = (Axis)(widget - BRSW_PLATFORM_DIR_X);
01207 this->LowerWidget(_railstation.orientation + BRSW_PLATFORM_DIR_X);
01208 SndPlayFx(SND_15_BEEP);
01209 this->SetDirty();
01210 DeleteWindowById(WC_SELECT_STATION, 0);
01211 break;
01212
01213 case BRSW_PLATFORM_NUM_1:
01214 case BRSW_PLATFORM_NUM_2:
01215 case BRSW_PLATFORM_NUM_3:
01216 case BRSW_PLATFORM_NUM_4:
01217 case BRSW_PLATFORM_NUM_5:
01218 case BRSW_PLATFORM_NUM_6:
01219 case BRSW_PLATFORM_NUM_7: {
01220 this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
01221 this->RaiseWidget(BRSW_PLATFORM_DRAG_N_DROP);
01222
01223 _settings_client.gui.station_numtracks = widget - BRSW_PLATFORM_NUM_BEGIN;
01224 _settings_client.gui.station_dragdrop = false;
01225
01226 _settings_client.gui.station_dragdrop = false;
01227
01228 const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class, _railstation.station_type) : NULL;
01229 if (statspec != NULL && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
01230
01231 for (uint i = 0; i < 7; i++) {
01232 if (!HasBit(statspec->disallowed_lengths, i)) {
01233 this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
01234 _settings_client.gui.station_platlength = i + 1;
01235 break;
01236 }
01237 }
01238 }
01239
01240 this->LowerWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
01241 this->LowerWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
01242 SndPlayFx(SND_15_BEEP);
01243 this->SetDirty();
01244 DeleteWindowById(WC_SELECT_STATION, 0);
01245 break;
01246 }
01247
01248 case BRSW_PLATFORM_LEN_1:
01249 case BRSW_PLATFORM_LEN_2:
01250 case BRSW_PLATFORM_LEN_3:
01251 case BRSW_PLATFORM_LEN_4:
01252 case BRSW_PLATFORM_LEN_5:
01253 case BRSW_PLATFORM_LEN_6:
01254 case BRSW_PLATFORM_LEN_7: {
01255 this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
01256 this->RaiseWidget(BRSW_PLATFORM_DRAG_N_DROP);
01257
01258 _settings_client.gui.station_platlength = widget - BRSW_PLATFORM_LEN_BEGIN;
01259 _settings_client.gui.station_dragdrop = false;
01260
01261 _settings_client.gui.station_dragdrop = false;
01262
01263 const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class, _railstation.station_type) : NULL;
01264 if (statspec != NULL && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
01265
01266 for (uint i = 0; i < 7; i++) {
01267 if (!HasBit(statspec->disallowed_platforms, i)) {
01268 this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
01269 _settings_client.gui.station_numtracks = i + 1;
01270 break;
01271 }
01272 }
01273 }
01274
01275 this->LowerWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
01276 this->LowerWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
01277 SndPlayFx(SND_15_BEEP);
01278 this->SetDirty();
01279 DeleteWindowById(WC_SELECT_STATION, 0);
01280 break;
01281 }
01282
01283 case BRSW_PLATFORM_DRAG_N_DROP: {
01284 _settings_client.gui.station_dragdrop ^= true;
01285
01286 this->ToggleWidgetLoweredState(BRSW_PLATFORM_DRAG_N_DROP);
01287
01288
01289 const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class, _railstation.station_type) : NULL;
01290 if (statspec != NULL && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
01291 for (uint i = 0; i < 7; i++) {
01292 if (!HasBit(statspec->disallowed_lengths, i)) {
01293 this->RaiseWidget(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN);
01294 _settings_client.gui.station_platlength = i + 1;
01295 break;
01296 }
01297 }
01298 }
01299 if (statspec != NULL && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
01300 for (uint i = 0; i < 7; i++) {
01301 if (!HasBit(statspec->disallowed_platforms, i)) {
01302 this->RaiseWidget(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN);
01303 _settings_client.gui.station_numtracks = i + 1;
01304 break;
01305 }
01306 }
01307 }
01308
01309 this->SetWidgetLoweredState(_settings_client.gui.station_numtracks + BRSW_PLATFORM_NUM_BEGIN, !_settings_client.gui.station_dragdrop);
01310 this->SetWidgetLoweredState(_settings_client.gui.station_platlength + BRSW_PLATFORM_LEN_BEGIN, !_settings_client.gui.station_dragdrop);
01311 SndPlayFx(SND_15_BEEP);
01312 this->SetDirty();
01313 DeleteWindowById(WC_SELECT_STATION, 0);
01314 break;
01315 }
01316
01317 case BRSW_HIGHLIGHT_OFF:
01318 case BRSW_HIGHLIGHT_ON:
01319 _settings_client.gui.station_show_coverage = (widget != BRSW_HIGHLIGHT_OFF);
01320
01321 this->SetWidgetLoweredState(BRSW_HIGHLIGHT_OFF, !_settings_client.gui.station_show_coverage);
01322 this->SetWidgetLoweredState(BRSW_HIGHLIGHT_ON, _settings_client.gui.station_show_coverage);
01323 SndPlayFx(SND_15_BEEP);
01324 this->SetDirty();
01325 break;
01326
01327 case BRSW_NEWST_LIST: {
01328 int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, BRSW_NEWST_LIST, 0, this->line_height);
01329 if (y >= (int)StationClass::GetCount()) return;
01330 for (uint i = 0; i < StationClass::GetCount(); i++) {
01331 if (i == STAT_CLASS_WAYP) continue;
01332 if (y == 0) {
01333 if (_railstation.station_class != (StationClassID)i) {
01334 _railstation.station_class = (StationClassID)i;
01335 _railstation.station_count = StationClass::GetCount(_railstation.station_class);
01336 _railstation.station_type = min((int)_railstation.station_type, max(0, (int)_railstation.station_count - 1));
01337
01338 this->CheckSelectedSize(StationClass::Get(_railstation.station_class, _railstation.station_type));
01339
01340 NWidgetMatrix *matrix = this->GetWidget<NWidgetMatrix>(BRSW_MATRIX);
01341 matrix->SetCount(_railstation.station_count);
01342 matrix->SetClicked(_railstation.station_type);
01343 }
01344 SndPlayFx(SND_15_BEEP);
01345 this->SetDirty();
01346 DeleteWindowById(WC_SELECT_STATION, 0);
01347 break;
01348 }
01349 y--;
01350 }
01351 break;
01352 }
01353
01354 case BRSW_IMAGE: {
01355 int y = GB(widget, 16, 16);
01356 if (y >= _railstation.station_count) return;
01357
01358
01359 const StationSpec *statspec = StationClass::Get(_railstation.station_class, y);
01360 if (statspec != NULL && HasBit(statspec->callback_mask, CBM_STATION_AVAIL) &&
01361 GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) return;
01362
01363 _railstation.station_type = y;
01364
01365 this->CheckSelectedSize(statspec);
01366 this->GetWidget<NWidgetMatrix>(BRSW_MATRIX)->SetClicked(_railstation.station_type);
01367
01368 SndPlayFx(SND_15_BEEP);
01369 this->SetDirty();
01370 DeleteWindowById(WC_SELECT_STATION, 0);
01371 break;
01372 }
01373 }
01374 }
01375
01376 virtual void OnTick()
01377 {
01378 CheckRedrawStationCoverage(this);
01379 }
01380 };
01381
01382 static const NWidgetPart _nested_station_builder_widgets[] = {
01383 NWidget(NWID_HORIZONTAL),
01384 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
01385 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_RAIL_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
01386 EndContainer(),
01387 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
01388 NWidget(NWID_HORIZONTAL),
01389 NWidget(NWID_VERTICAL),
01390 NWidget(NWID_SELECTION, INVALID_COLOUR, BRSW_SHOW_NEWST_ADDITIONS),
01391 NWidget(NWID_HORIZONTAL), SetPIP(7, 0, 7), SetPadding(2, 0, 1, 0),
01392 NWidget(WWT_MATRIX, COLOUR_GREY, BRSW_NEWST_LIST), SetMinimalSize(122, 71), SetFill(1, 0),
01393 SetDataTip(0x501, STR_STATION_BUILD_STATION_CLASS_TOOLTIP), SetScrollbar(BRSW_NEWST_SCROLL),
01394 NWidget(NWID_VSCROLLBAR, COLOUR_GREY, BRSW_NEWST_SCROLL),
01395 EndContainer(),
01396 EndContainer(),
01397 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_ORIENTATION, STR_NULL), SetPadding(1, 2, 0, 2),
01398 NWidget(NWID_HORIZONTAL),
01399 NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0),
01400 NWidget(WWT_PANEL, COLOUR_GREY, BRSW_PLATFORM_DIR_X), SetMinimalSize(66, 48), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(),
01401 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01402 NWidget(WWT_PANEL, COLOUR_GREY, BRSW_PLATFORM_DIR_Y), SetMinimalSize(66, 48), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(),
01403 NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0),
01404 EndContainer(),
01405 NWidget(WWT_LABEL, COLOUR_DARK_GREEN, BRSW_SHOW_NEWST_TYPE), SetMinimalSize(144, 11), SetDataTip(STR_ORANGE_STRING, STR_NULL), SetPadding(1, 2, 4, 2),
01406 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_NUMBER_OF_TRACKS, STR_NULL), SetPadding(0, 2, 0, 2),
01407 NWidget(NWID_HORIZONTAL),
01408 NWidget(NWID_SPACER), SetFill(1, 0),
01409 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_1), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_1, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01410 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_2), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_2, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01411 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_3), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_3, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01412 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_4), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_4, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01413 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_5), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_5, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01414 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_6), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_6, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01415 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_NUM_7), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_7, STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP),
01416 NWidget(NWID_SPACER), SetFill(1, 0),
01417 EndContainer(),
01418 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_PLATFORM_LENGTH, STR_NULL), SetPadding(2, 2, 0, 2),
01419 NWidget(NWID_HORIZONTAL),
01420 NWidget(NWID_SPACER), SetFill(1, 0),
01421 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_1), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_1, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01422 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_2), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_2, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01423 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_3), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_3, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01424 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_4), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_4, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01425 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_5), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_5, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01426 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_6), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_6, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01427 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_PLATFORM_LEN_7), SetMinimalSize(15, 12), SetDataTip(STR_BLACK_7, STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP),
01428 NWidget(NWID_SPACER), SetFill(1, 0),
01429 EndContainer(),
01430 NWidget(NWID_SPACER), SetMinimalSize(0, 2),
01431 NWidget(NWID_HORIZONTAL),
01432 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01433 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),
01434 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01435 EndContainer(),
01436 NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetPadding(3, 2, 0, 2),
01437 NWidget(NWID_HORIZONTAL),
01438 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01439 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_HIGHLIGHT_OFF), SetMinimalSize(60, 12),
01440 SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
01441 NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_HIGHLIGHT_ON), SetMinimalSize(60, 12),
01442 SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
01443 NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
01444 EndContainer(),
01445 EndContainer(),
01446 NWidget(NWID_SELECTION, INVALID_COLOUR, BRSW_SHOW_NEWST_MATRIX),
01447
01448 NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetScrollbar(BRSW_MATRIX_SCROLL),
01449 NWidget(NWID_HORIZONTAL),
01450 NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, BRSW_MATRIX), SetScrollbar(BRSW_MATRIX_SCROLL), SetPIP(0, 2, 0), SetPadding(2, 0, 0, 0),
01451 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BRSW_IMAGE), SetMinimalSize(66, 60),
01452 SetFill(0, 0), SetResize(0, 0), SetDataTip(0x0, STR_STATION_BUILD_STATION_TYPE_TOOLTIP), SetScrollbar(BRSW_MATRIX_SCROLL),
01453 EndContainer(),
01454 EndContainer(),
01455 NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, BRSW_MATRIX_SCROLL),
01456 EndContainer(),
01457 EndContainer(),
01458 EndContainer(),
01459 EndContainer(),
01460 NWidget(NWID_HORIZONTAL),
01461 NWidget(WWT_EMPTY, INVALID_COLOUR, BRSW_COVERAGE_TEXTS), SetFill(1, 1), SetResize(1, 0),
01462 NWidget(NWID_SELECTION, INVALID_COLOUR, BRSW_SHOW_NEWST_RESIZE),
01463 NWidget(NWID_VERTICAL),
01464 NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(0, 1), EndContainer(),
01465 NWidget(WWT_RESIZEBOX, COLOUR_DARK_GREEN),
01466 EndContainer(),
01467 EndContainer(),
01468 EndContainer(),
01469 EndContainer(),
01470 };
01471
01473 static const WindowDesc _station_builder_desc(
01474 WDP_AUTO, 350, 0,
01475 WC_BUILD_STATION, WC_BUILD_TOOLBAR,
01476 WDF_CONSTRUCTION,
01477 _nested_station_builder_widgets, lengthof(_nested_station_builder_widgets)
01478 );
01479
01481 static void ShowStationBuilder(Window *parent)
01482 {
01483 bool newstations = StationClass::GetCount() > 2 || StationClass::GetCount(STAT_CLASS_DFLT) != 1;
01484 new BuildRailStationWindow(&_station_builder_desc, parent, newstations);
01485 }
01486
01488 enum BuildSignalWidgets {
01489 BSW_SEMAPHORE_NORM,
01490 BSW_SEMAPHORE_ENTRY,
01491 BSW_SEMAPHORE_EXIT,
01492 BSW_SEMAPHORE_COMBO,
01493 BSW_SEMAPHORE_PBS,
01494 BSW_SEMAPHORE_PBS_OWAY,
01495 BSW_ELECTRIC_NORM,
01496 BSW_ELECTRIC_ENTRY,
01497 BSW_ELECTRIC_EXIT,
01498 BSW_ELECTRIC_COMBO,
01499 BSW_ELECTRIC_PBS,
01500 BSW_ELECTRIC_PBS_OWAY,
01501 BSW_CONVERT,
01502 BSW_DRAG_SIGNALS_DENSITY,
01503 BSW_DRAG_SIGNALS_DENSITY_LABEL,
01504 BSW_DRAG_SIGNALS_DENSITY_DECREASE,
01505 BSW_DRAG_SIGNALS_DENSITY_INCREASE,
01506 };
01507
01508 struct BuildSignalWindow : public PickerWindowBase {
01509 private:
01517 void DrawSignalSprite(byte widget_index, SpriteID image) const
01518 {
01519
01520 image += this->IsWidgetLowered(widget_index);
01521
01522
01523 const Sprite *sprite = GetSprite(image, ST_NORMAL);
01524
01525
01526
01527
01528
01529 int sprite_center_x_offset = sprite->x_offs + sprite->width / 2;
01530 int sprite_bottom_y_offset = sprite->height + sprite->y_offs;
01531
01532
01533
01534 const NWidgetBase *widget = this->GetWidget<NWidgetBase>(widget_index);
01535 int widget_center_x = widget->pos_x + widget->current_x / 2;
01536 int widget_bottom_y = widget->pos_y + widget->current_y - 2;
01537
01538
01539 DrawSprite(image, PAL_NONE,
01540 widget_center_x - sprite_center_x_offset + this->IsWidgetLowered(widget_index),
01541 widget_bottom_y - sprite_bottom_y_offset + this->IsWidgetLowered(widget_index));
01542 }
01543
01544 public:
01545 BuildSignalWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(parent)
01546 {
01547 this->InitNested(desc, TRANSPORT_RAIL);
01548 this->OnInvalidateData();
01549 }
01550
01551 virtual void SetStringParameters(int widget) const
01552 {
01553 switch (widget) {
01554 case BSW_DRAG_SIGNALS_DENSITY_LABEL:
01555 SetDParam(0, _settings_client.gui.drag_signals_density);
01556 break;
01557 }
01558 }
01559
01560 virtual void DrawWidget(const Rect &r, int widget) const
01561 {
01562 if (IsInsideMM(widget, BSW_SEMAPHORE_NORM, BSW_ELECTRIC_PBS_OWAY + 1)) {
01563
01564 const SpriteID _signal_lookup[] = {
01565 SPR_IMG_SIGNAL_SEMAPHORE_NORM, SPR_IMG_SIGNAL_SEMAPHORE_ENTRY, SPR_IMG_SIGNAL_SEMAPHORE_EXIT,
01566 SPR_IMG_SIGNAL_SEMAPHORE_COMBO, SPR_IMG_SIGNAL_SEMAPHORE_PBS, SPR_IMG_SIGNAL_SEMAPHORE_PBS_OWAY,
01567
01568 SPR_IMG_SIGNAL_ELECTRIC_NORM, SPR_IMG_SIGNAL_ELECTRIC_ENTRY, SPR_IMG_SIGNAL_ELECTRIC_EXIT,
01569 SPR_IMG_SIGNAL_ELECTRIC_COMBO, SPR_IMG_SIGNAL_ELECTRIC_PBS, SPR_IMG_SIGNAL_ELECTRIC_PBS_OWAY
01570 };
01571
01572 this->DrawSignalSprite(widget, _signal_lookup[widget - BSW_SEMAPHORE_NORM]);
01573 }
01574 }
01575
01576 virtual void OnClick(Point pt, int widget, int click_count)
01577 {
01578 switch (widget) {
01579 case BSW_SEMAPHORE_NORM:
01580 case BSW_SEMAPHORE_ENTRY:
01581 case BSW_SEMAPHORE_EXIT:
01582 case BSW_SEMAPHORE_COMBO:
01583 case BSW_SEMAPHORE_PBS:
01584 case BSW_SEMAPHORE_PBS_OWAY:
01585 case BSW_ELECTRIC_NORM:
01586 case BSW_ELECTRIC_ENTRY:
01587 case BSW_ELECTRIC_EXIT:
01588 case BSW_ELECTRIC_COMBO:
01589 case BSW_ELECTRIC_PBS:
01590 case BSW_ELECTRIC_PBS_OWAY:
01591 this->RaiseWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type);
01592
01593 _cur_signal_type = (SignalType)((uint)((widget - BSW_SEMAPHORE_NORM) % (SIGTYPE_LAST + 1)));
01594 _cur_signal_variant = widget >= BSW_ELECTRIC_NORM ? SIG_ELECTRIC : SIG_SEMAPHORE;
01595 break;
01596
01597 case BSW_CONVERT:
01598 _convert_signal_button = !_convert_signal_button;
01599 break;
01600
01601 case BSW_DRAG_SIGNALS_DENSITY_DECREASE:
01602 if (_settings_client.gui.drag_signals_density > 1) {
01603 _settings_client.gui.drag_signals_density--;
01604 SetWindowDirty(WC_GAME_OPTIONS, 0);
01605 }
01606 break;
01607
01608 case BSW_DRAG_SIGNALS_DENSITY_INCREASE:
01609 if (_settings_client.gui.drag_signals_density < 20) {
01610 _settings_client.gui.drag_signals_density++;
01611 SetWindowDirty(WC_GAME_OPTIONS, 0);
01612 }
01613 break;
01614
01615 default: break;
01616 }
01617
01618 this->InvalidateData();
01619 }
01620
01621 virtual void OnInvalidateData(int data = 0)
01622 {
01623 this->LowerWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type);
01624
01625 this->SetWidgetLoweredState(BSW_CONVERT, _convert_signal_button);
01626
01627 this->SetWidgetDisabledState(BSW_DRAG_SIGNALS_DENSITY_DECREASE, _settings_client.gui.drag_signals_density == 1);
01628 this->SetWidgetDisabledState(BSW_DRAG_SIGNALS_DENSITY_INCREASE, _settings_client.gui.drag_signals_density == 20);
01629 }
01630 };
01631
01633 static const NWidgetPart _nested_signal_builder_widgets[] = {
01634 NWidget(NWID_HORIZONTAL),
01635 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
01636 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_BUILD_SIGNAL_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
01637 EndContainer(),
01638 NWidget(NWID_VERTICAL, NC_EQUALSIZE),
01639 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
01640 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_NORM), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP), EndContainer(), SetFill(1, 1),
01641 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_ENTRY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP), EndContainer(), SetFill(1, 1),
01642 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_EXIT), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP), EndContainer(), SetFill(1, 1),
01643 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_COMBO), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP), EndContainer(), SetFill(1, 1),
01644 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_PBS), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP), EndContainer(), SetFill(1, 1),
01645 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_SEMAPHORE_PBS_OWAY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP), EndContainer(), SetFill(1, 1),
01646 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, BSW_CONVERT), SetDataTip(SPR_IMG_SIGNAL_CONVERT, STR_BUILD_SIGNAL_CONVERT_TOOLTIP), SetFill(1, 1),
01647 EndContainer(),
01648 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
01649 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_NORM), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP), EndContainer(), SetFill(1, 1),
01650 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_ENTRY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TOOLTIP), EndContainer(), SetFill(1, 1),
01651 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_EXIT), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP), EndContainer(), SetFill(1, 1),
01652 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_COMBO), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP), EndContainer(), SetFill(1, 1),
01653 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_PBS), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP), EndContainer(), SetFill(1, 1),
01654 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_ELECTRIC_PBS_OWAY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP), EndContainer(), SetFill(1, 1),
01655 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BSW_DRAG_SIGNALS_DENSITY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(1, 1),
01656 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),
01657 NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
01658 NWidget(NWID_SPACER), SetFill(1, 0),
01659 NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, BSW_DRAG_SIGNALS_DENSITY_DECREASE), SetMinimalSize(9, 12), SetDataTip(AWV_DECREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP),
01660 NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, BSW_DRAG_SIGNALS_DENSITY_INCREASE), SetMinimalSize(9, 12), SetDataTip(AWV_INCREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP),
01661 NWidget(NWID_SPACER), SetFill(1, 0),
01662 EndContainer(),
01663 NWidget(NWID_SPACER), SetMinimalSize(0, 2), SetFill(1, 0),
01664 EndContainer(),
01665 EndContainer(),
01666 EndContainer(),
01667 };
01668
01670 static const WindowDesc _signal_builder_desc(
01671 WDP_AUTO, 0, 0,
01672 WC_BUILD_SIGNAL, WC_BUILD_TOOLBAR,
01673 WDF_UNCLICK_BUTTONS | WDF_CONSTRUCTION,
01674 _nested_signal_builder_widgets, lengthof(_nested_signal_builder_widgets)
01675 );
01676
01680 static void ShowSignalBuilder(Window *parent)
01681 {
01682 new BuildSignalWindow(&_signal_builder_desc, parent);
01683 }
01684
01686 enum BuildRailDepotWidgets {
01687 BRDW_DEPOT_NE,
01688 BRDW_DEPOT_SE,
01689 BRDW_DEPOT_SW,
01690 BRDW_DEPOT_NW,
01691 };
01692
01693 struct BuildRailDepotWindow : public PickerWindowBase {
01694 BuildRailDepotWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(parent)
01695 {
01696 this->InitNested(desc, TRANSPORT_RAIL);
01697 this->LowerWidget(_build_depot_direction + BRDW_DEPOT_NE);
01698 }
01699
01700 virtual void DrawWidget(const Rect &r, int widget) const
01701 {
01702 if (!IsInsideMM(widget, BRDW_DEPOT_NE, BRDW_DEPOT_NW + 1)) return;
01703
01704 DrawTrainDepotSprite(r.left - 1, r.top, widget - BRDW_DEPOT_NE + DIAGDIR_NE, _cur_railtype);
01705 }
01706
01707 virtual void OnClick(Point pt, int widget, int click_count)
01708 {
01709 switch (widget) {
01710 case BRDW_DEPOT_NE:
01711 case BRDW_DEPOT_SE:
01712 case BRDW_DEPOT_SW:
01713 case BRDW_DEPOT_NW:
01714 this->RaiseWidget(_build_depot_direction + BRDW_DEPOT_NE);
01715 _build_depot_direction = (DiagDirection)(widget - BRDW_DEPOT_NE);
01716 this->LowerWidget(_build_depot_direction + BRDW_DEPOT_NE);
01717 SndPlayFx(SND_15_BEEP);
01718 this->SetDirty();
01719 break;
01720 }
01721 }
01722 };
01723
01725 static const NWidgetPart _nested_build_depot_widgets[] = {
01726 NWidget(NWID_HORIZONTAL),
01727 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
01728 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_BUILD_DEPOT_TRAIN_ORIENTATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
01729 EndContainer(),
01730 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
01731 NWidget(NWID_SPACER), SetMinimalSize(0, 3),
01732 NWidget(NWID_HORIZONTAL_LTR),
01733 NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
01734 NWidget(NWID_VERTICAL),
01735 NWidget(WWT_PANEL, COLOUR_GREY, BRDW_DEPOT_NW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
01736 EndContainer(),
01737 NWidget(NWID_SPACER), SetMinimalSize(0, 2),
01738 NWidget(WWT_PANEL, COLOUR_GREY, BRDW_DEPOT_SW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
01739 EndContainer(),
01740 EndContainer(),
01741 NWidget(NWID_SPACER), SetMinimalSize(2, 0),
01742 NWidget(NWID_VERTICAL),
01743 NWidget(WWT_PANEL, COLOUR_GREY, BRDW_DEPOT_NE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
01744 EndContainer(),
01745 NWidget(NWID_SPACER), SetMinimalSize(0, 2),
01746 NWidget(WWT_PANEL, COLOUR_GREY, BRDW_DEPOT_SE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
01747 EndContainer(),
01748 EndContainer(),
01749 NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
01750 EndContainer(),
01751 NWidget(NWID_SPACER), SetMinimalSize(0, 3),
01752 EndContainer(),
01753 };
01754
01755 static const WindowDesc _build_depot_desc(
01756 WDP_AUTO, 0, 0,
01757 WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
01758 WDF_CONSTRUCTION,
01759 _nested_build_depot_widgets, lengthof(_nested_build_depot_widgets)
01760 );
01761
01762 static void ShowBuildTrainDepotPicker(Window *parent)
01763 {
01764 new BuildRailDepotWindow(&_build_depot_desc, parent);
01765 }
01766
01768 enum BuildRailWaypointWidgets {
01769 BRWW_WAYPOINT_MATRIX,
01770 BRWW_WAYPOINT,
01771 BRWW_SCROLL,
01772 };
01773
01774 struct BuildRailWaypointWindow : PickerWindowBase {
01775 BuildRailWaypointWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(parent)
01776 {
01777 this->CreateNestedTree(desc);
01778
01779 NWidgetMatrix *matrix = this->GetWidget<NWidgetMatrix>(BRWW_WAYPOINT_MATRIX);
01780 matrix->SetScrollbar(this->GetScrollbar(BRWW_SCROLL));
01781
01782 this->FinishInitNested(desc, TRANSPORT_RAIL);
01783
01784 matrix->SetCount(_waypoint_count);
01785 matrix->SetClicked(_cur_waypoint_type);
01786 }
01787
01788 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
01789 {
01790 switch (widget) {
01791 case BRWW_WAYPOINT_MATRIX:
01792
01793 size->width += resize->width * 2;
01794 size->height += resize->height * 2;
01795
01796
01797 resize->height = 1;
01798 break;
01799 }
01800 }
01801
01802 virtual void DrawWidget(const Rect &r, int widget) const
01803 {
01804 switch (GB(widget, 0, 16)) {
01805 case BRWW_WAYPOINT: {
01806 byte type = GB(widget, 16, 16);
01807 const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP, type);
01808 DrawWaypointSprite(r.left + TILE_PIXELS, r.bottom - TILE_PIXELS, type, _cur_railtype);
01809
01810 if (statspec != NULL &&
01811 HasBit(statspec->callback_mask, CBM_STATION_AVAIL) &&
01812 GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) {
01813 GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, 0, FILLRECT_CHECKER);
01814 }
01815 }
01816 }
01817 }
01818
01819 virtual void OnClick(Point pt, int widget, int click_count)
01820 {
01821 switch (GB(widget, 0, 16)) {
01822 case BRWW_WAYPOINT: {
01823 byte type = GB(widget, 16, 16);
01824 this->GetWidget<NWidgetMatrix>(BRWW_WAYPOINT_MATRIX)->SetClicked(_cur_waypoint_type);
01825
01826
01827 const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP, type);
01828 if (statspec != NULL &&
01829 HasBit(statspec->callback_mask, CBM_STATION_AVAIL) &&
01830 GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) return;
01831
01832 _cur_waypoint_type = type;
01833 this->GetWidget<NWidgetMatrix>(BRWW_WAYPOINT_MATRIX)->SetClicked(_cur_waypoint_type);
01834 SndPlayFx(SND_15_BEEP);
01835 this->SetDirty();
01836 break;
01837 }
01838 }
01839 }
01840 };
01841
01843 static const NWidgetPart _nested_build_waypoint_widgets[] = {
01844 NWidget(NWID_HORIZONTAL),
01845 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
01846 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_WAYPOINT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
01847 EndContainer(),
01848 NWidget(NWID_HORIZONTAL),
01849 NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, BRWW_WAYPOINT_MATRIX), SetPIP(3, 2, 3), SetScrollbar(BRWW_SCROLL),
01850 NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BRWW_WAYPOINT), SetMinimalSize(66, 60), SetDataTip(0x0, STR_WAYPOINT_GRAPHICS_TOOLTIP), EndContainer(),
01851 EndContainer(),
01852 NWidget(NWID_VERTICAL),
01853 NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, BRWW_SCROLL),
01854 NWidget(WWT_RESIZEBOX, COLOUR_DARK_GREEN),
01855 EndContainer(),
01856 EndContainer(),
01857 };
01858
01859 static const WindowDesc _build_waypoint_desc(
01860 WDP_AUTO, 0, 0,
01861 WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
01862 WDF_CONSTRUCTION,
01863 _nested_build_waypoint_widgets, lengthof(_nested_build_waypoint_widgets)
01864 );
01865
01866 static void ShowBuildWaypointPicker(Window *parent)
01867 {
01868 new BuildRailWaypointWindow(&_build_waypoint_desc, parent);
01869 }
01870
01874 void InitializeRailGui()
01875 {
01876 _build_depot_direction = DIAGDIR_NW;
01877 }
01878
01883 void ReinitGuiAfterToggleElrail(bool disable)
01884 {
01885 extern RailType _last_built_railtype;
01886 if (disable && _last_built_railtype == RAILTYPE_ELECTRIC) {
01887 _last_built_railtype = _cur_railtype = RAILTYPE_RAIL;
01888 BuildRailToolbarWindow *w = dynamic_cast<BuildRailToolbarWindow *>(FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_RAIL));
01889 if (w != NULL) w->ModifyRailType(_cur_railtype);
01890 }
01891 MarkWholeScreenDirty();
01892 }
01893
01895 static void SetDefaultRailGui()
01896 {
01897 if (_local_company == COMPANY_SPECTATOR || !Company::IsValidID(_local_company)) return;
01898
01899 extern RailType _last_built_railtype;
01900 RailType rt = (RailType)(_settings_client.gui.default_rail_type + RAILTYPE_END);
01901 if (rt == DEF_RAILTYPE_MOST_USED) {
01902
01903 RailType count[RAILTYPE_END];
01904 memset(count, 0, sizeof(count));
01905 for (TileIndex t = 0; t < MapSize(); t++) {
01906 if (IsTileType(t, MP_RAILWAY) || IsLevelCrossingTile(t) || HasStationTileRail(t) ||
01907 (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL)) {
01908 count[GetRailType(t)]++;
01909 }
01910 }
01911
01912 rt = RAILTYPE_RAIL;
01913 for (RailType r = RAILTYPE_ELECTRIC; r < RAILTYPE_END; r++) {
01914 if (count[r] >= count[rt]) rt = r;
01915 }
01916
01917
01918 if (count[rt] == 0) rt = DEF_RAILTYPE_FIRST;
01919 }
01920 switch (rt) {
01921 case DEF_RAILTYPE_FIRST:
01922 rt = RAILTYPE_RAIL;
01923 while (rt < RAILTYPE_END && !HasRailtypeAvail(_local_company, rt)) rt++;
01924 break;
01925
01926 case DEF_RAILTYPE_LAST:
01927 rt = GetBestRailtype(_local_company);
01928 break;
01929
01930 default:
01931 break;
01932 }
01933
01934 _last_built_railtype = _cur_railtype = rt;
01935 BuildRailToolbarWindow *w = dynamic_cast<BuildRailToolbarWindow *>(FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_RAIL));
01936 if (w != NULL) w->ModifyRailType(_cur_railtype);
01937 }
01938
01945 bool ResetSignalVariant(int32 p = 0)
01946 {
01947 SignalVariant new_variant = (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC);
01948
01949 if (new_variant != _cur_signal_variant) {
01950 Window *w = FindWindowById(WC_BUILD_SIGNAL, 0);
01951 if (w != NULL) {
01952 w->SetDirty();
01953 w->RaiseWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type);
01954 }
01955 _cur_signal_variant = new_variant;
01956 }
01957
01958 return true;
01959 }
01960
01965 void InitializeRailGUI()
01966 {
01967 SetDefaultRailGui();
01968
01969 _convert_signal_button = false;
01970 _cur_signal_type = _default_signal_type[_settings_client.gui.default_signal_type];
01971 ResetSignalVariant();
01972 }
01973
01980 static bool CompareRailTypes(const DropDownListItem *first, const DropDownListItem *second)
01981 {
01982 return GetRailTypeInfo((RailType)first->result)->sorting_order < GetRailTypeInfo((RailType)second->result)->sorting_order;
01983 }
01984
01990 DropDownList *GetRailTypeDropDownList(bool for_replacement)
01991 {
01992 RailTypes used_railtypes = RAILTYPES_NONE;
01993
01994
01995 Engine *e;
01996 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
01997 if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue;
01998
01999 used_railtypes |= GetRailTypeInfo(e->u.rail.railtype)->introduces_railtypes;
02000 }
02001
02002
02003 used_railtypes = AddDateIntroducedRailTypes(used_railtypes, MAX_DAY);
02004
02005 const Company *c = Company::Get(_local_company);
02006 DropDownList *list = new DropDownList();
02007 for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
02008
02009 if (!HasBit(used_railtypes, rt)) continue;
02010
02011 const RailtypeInfo *rti = GetRailTypeInfo(rt);
02012
02013 if (rti->label == 0) continue;
02014
02015 StringID str = for_replacement ? rti->strings.replace_text : (rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING);
02016 DropDownListParamStringItem *item = new DropDownListParamStringItem(str, rt, !HasBit(c->avail_railtypes, rt));
02017 item->SetParam(0, rti->strings.menu_text);
02018 item->SetParam(1, rti->max_speed);
02019 list->push_back(item);
02020 }
02021 list->sort(CompareRailTypes);
02022 return list;
02023 }