road_gui.cpp

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
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 "road_cmd.h"
00020 #include "station_func.h"
00021 #include "window_func.h"
00022 #include "vehicle_func.h"
00023 #include "sound_func.h"
00024 #include "company_func.h"
00025 #include "tunnelbridge.h"
00026 #include "tunnelbridge_map.h"
00027 #include "tilehighlight_func.h"
00028 #include "company_base.h"
00029 #include "hotkeys.h"
00030 #include "road_gui.h"
00031 
00032 #include "table/strings.h"
00033 
00034 static void ShowRVStationPicker(Window *parent, RoadStopType rs);
00035 static void ShowRoadDepotPicker(Window *parent);
00036 
00037 static bool _remove_button_clicked;
00038 static bool _one_way_button_clicked;
00039 
00044 enum RoadFlags {
00045   RF_NONE             = 0x00,
00046   RF_START_HALFROAD_Y = 0x01,    // The start tile in Y-dir should have only a half road
00047   RF_END_HALFROAD_Y   = 0x02,    // The end tile in Y-dir should have only a half road
00048   RF_DIR_Y            = 0x04,    // The direction is Y-dir
00049   RF_DIR_X            = RF_NONE, // Dummy; Dir X is set when RF_DIR_Y is not set
00050   RF_START_HALFROAD_X = 0x08,    // The start tile in X-dir should have only a half road
00051   RF_END_HALFROAD_X   = 0x10,    // The end tile in X-dir should have only a half road
00052 };
00053 DECLARE_ENUM_AS_BIT_SET(RoadFlags)
00054 
00055 static RoadFlags _place_road_flag;
00056 
00057 static RoadType _cur_roadtype;
00058 
00059 static DiagDirection _road_depot_orientation;
00060 static DiagDirection _road_station_picker_orientation;
00061 
00062 void CcPlaySound1D(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
00063 {
00064   if (result.Succeeded()) SndPlayTileFx(SND_1F_SPLAT, tile);
00065 }
00066 
00071 static void PlaceRoad_Bridge(TileIndex tile, Window *w)
00072 {
00073   if (IsBridgeTile(tile)) {
00074     TileIndex other_tile = GetOtherTunnelBridgeEnd(tile);
00075     Point pt = {0, 0};
00076     w->OnPlaceMouseUp(VPM_X_OR_Y, DDSP_BUILD_BRIDGE, pt, tile, other_tile);
00077   } else {
00078     VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE);
00079   }
00080 }
00081 
00091 void CcBuildRoadTunnel(const CommandCost &result, TileIndex start_tile, uint32 p1, uint32 p2)
00092 {
00093   if (result.Succeeded()) {
00094     SndPlayTileFx(SND_20_SPLAT_2, start_tile);
00095     if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
00096 
00097     DiagDirection start_direction = ReverseDiagDir(GetTunnelBridgeDirection(start_tile));
00098     ConnectRoadToStructure(start_tile, start_direction);
00099 
00100     TileIndex end_tile = GetOtherTunnelBridgeEnd(start_tile);
00101     DiagDirection end_direction = ReverseDiagDir(GetTunnelBridgeDirection(end_tile));
00102     ConnectRoadToStructure(end_tile, end_direction);
00103   } else {
00104     SetRedErrorSquare(_build_tunnel_endtile);
00105   }
00106 }
00107 
00109 struct RoadTypeInfo {
00110   StringID err_build_road;        
00111   StringID err_remove_road;       
00112   StringID err_depot;             
00113   StringID err_build_station[2];  
00114   StringID err_remove_station[2]; 
00115 
00116   StringID picker_title[2];       
00117   StringID picker_tooltip[2];     
00118 
00119   SpriteID cursor_nesw;           
00120   SpriteID cursor_nwse;           
00121   SpriteID cursor_autoroad;       
00122 };
00123 
00125 static const RoadTypeInfo _road_type_infos[] = {
00126   {
00127     STR_ERROR_CAN_T_BUILD_ROAD_HERE,
00128     STR_ERROR_CAN_T_REMOVE_ROAD_FROM,
00129     STR_ERROR_CAN_T_BUILD_ROAD_DEPOT,
00130     { STR_ERROR_CAN_T_BUILD_BUS_STATION,         STR_ERROR_CAN_T_BUILD_TRUCK_STATION          },
00131     { STR_ERROR_CAN_T_REMOVE_BUS_STATION,        STR_ERROR_CAN_T_REMOVE_TRUCK_STATION         },
00132     { STR_STATION_BUILD_BUS_ORIENTATION,         STR_STATION_BUILD_TRUCK_ORIENTATION          },
00133     { STR_STATION_BUILD_BUS_ORIENTATION_TOOLTIP, STR_STATION_BUILD_TRUCK_ORIENTATION_TOOLTIP  },
00134 
00135     SPR_CURSOR_ROAD_NESW,
00136     SPR_CURSOR_ROAD_NWSE,
00137     SPR_CURSOR_AUTOROAD,
00138   },
00139   {
00140     STR_ERROR_CAN_T_BUILD_TRAMWAY_HERE,
00141     STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM,
00142     STR_ERROR_CAN_T_BUILD_TRAM_DEPOT,
00143     { STR_ERROR_CAN_T_BUILD_PASSENGER_TRAM_STATION,         STR_ERROR_CAN_T_BUILD_CARGO_TRAM_STATION         },
00144     { STR_ERROR_CAN_T_REMOVE_PASSENGER_TRAM_STATION,        STR_ERROR_CAN_T_REMOVE_CARGO_TRAM_STATION        },
00145     { STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION,         STR_STATION_BUILD_CARGO_TRAM_ORIENTATION         },
00146     { STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION_TOOLTIP, STR_STATION_BUILD_CARGO_TRAM_ORIENTATION_TOOLTIP },
00147 
00148     SPR_CURSOR_TRAMWAY_NESW,
00149     SPR_CURSOR_TRAMWAY_NWSE,
00150     SPR_CURSOR_AUTOTRAM,
00151   },
00152 };
00153 
00159 void ConnectRoadToStructure(TileIndex tile, DiagDirection direction)
00160 {
00161   tile += TileOffsByDiagDir(direction);
00162   /* if there is a roadpiece just outside of the station entrance, build a connecting route */
00163   if (IsNormalRoadTile(tile)) {
00164     if (GetRoadBits(tile, _cur_roadtype) != ROAD_NONE) {
00165       DoCommandP(tile, _cur_roadtype << 4 | DiagDirToRoadBits(ReverseDiagDir(direction)), 0, CMD_BUILD_ROAD);
00166     }
00167   }
00168 }
00169 
00170 void CcRoadDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
00171 {
00172   if (result.Failed()) return;
00173 
00174   DiagDirection dir = (DiagDirection)GB(p1, 0, 2);
00175   SndPlayTileFx(SND_1F_SPLAT, tile);
00176   if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
00177   ConnectRoadToStructure(tile, dir);
00178 }
00179 
00194 void CcRoadStop(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
00195 {
00196   if (result.Failed()) return;
00197 
00198   DiagDirection dir = (DiagDirection)GB(p2, 6, 2);
00199   SndPlayTileFx(SND_1F_SPLAT, tile);
00200   if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
00201   TileArea roadstop_area(tile, GB(p1, 0, 8), GB(p1, 8, 8));
00202   TILE_AREA_LOOP(cur_tile, roadstop_area) {
00203     ConnectRoadToStructure(cur_tile, dir);
00204     /* For a drive-through road stop build connecting road for other entrance. */
00205     if (HasBit(p2, 1)) ConnectRoadToStructure(cur_tile, ReverseDiagDir(dir));
00206   }
00207 }
00208 
00219 static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, uint32 cmd)
00220 {
00221   uint8 ddir = _road_station_picker_orientation;
00222   SB(p2, 16, 16, INVALID_STATION); // no station to join
00223 
00224   if (ddir >= DIAGDIR_END) {
00225     SetBit(p2, 1); // It's a drive-through stop.
00226     ddir -= DIAGDIR_END; // Adjust picker result to actual direction.
00227   }
00228   p2 |= ddir << 6; // Set the DiagDirecion into p2 bits 6 and 7.
00229 
00230   TileArea ta(start_tile, end_tile);
00231   CommandContainer cmdcont = { ta.tile, ta.w | ta.h << 8, p2, cmd, CcRoadStop, "" };
00232   ShowSelectStationIfNeeded(cmdcont, ta);
00233 }
00234 
00239 static void PlaceRoad_BusStation(TileIndex tile)
00240 {
00241   if (_remove_button_clicked) {
00242     VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_REMOVE_BUSSTOP);
00243   } else {
00244     if (_road_station_picker_orientation < DIAGDIR_END) { // Not a drive-through stop.
00245       VpStartPlaceSizing(tile, (DiagDirToAxis(_road_station_picker_orientation) == AXIS_X) ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_BUSSTOP);
00246     } else {
00247       VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_BUSSTOP);
00248     }
00249     VpSetPlaceSizingLimit(_settings_game.station.station_spread);
00250   }
00251 }
00252 
00257 static void PlaceRoad_TruckStation(TileIndex tile)
00258 {
00259   if (_remove_button_clicked) {
00260     VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_REMOVE_TRUCKSTOP);
00261   } else {
00262     if (_road_station_picker_orientation < DIAGDIR_END) { // Not a drive-through stop.
00263       VpStartPlaceSizing(tile, (DiagDirToAxis(_road_station_picker_orientation) == AXIS_X) ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_TRUCKSTOP);
00264     } else {
00265       VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_TRUCKSTOP);
00266     }
00267     VpSetPlaceSizingLimit(_settings_game.station.station_spread);
00268   }
00269 }
00270 
00272 enum RoadToolbarWidgets {
00273   RTW_ROAD_X,
00274   RTW_ROAD_Y,
00275   RTW_AUTOROAD,
00276   RTW_DEMOLISH,
00277   RTW_DEPOT,
00278   RTW_BUS_STATION,
00279   RTW_TRUCK_STATION,
00280   RTW_ONE_WAY,
00281   RTW_BUILD_BRIDGE,
00282   RTW_BUILD_TUNNEL,
00283   RTW_REMOVE,
00284 };
00285 
00286 typedef void OnButtonClick(Window *w);
00287 
00288 
00293 static void ToggleRoadButton_Remove(Window *w)
00294 {
00295   w->ToggleWidgetLoweredState(RTW_REMOVE);
00296   w->SetWidgetDirty(RTW_REMOVE);
00297   _remove_button_clicked = w->IsWidgetLowered(RTW_REMOVE);
00298   SetSelectionRed(_remove_button_clicked);
00299 }
00300 
00306 static bool RoadToolbar_CtrlChanged(Window *w)
00307 {
00308   if (w->IsWidgetDisabled(RTW_REMOVE)) return false;
00309 
00310   /* allow ctrl to switch remove mode only for these widgets */
00311   for (uint i = RTW_ROAD_X; i <= RTW_AUTOROAD; i++) {
00312     if (w->IsWidgetLowered(i)) {
00313       ToggleRoadButton_Remove(w);
00314       return true;
00315     }
00316   }
00317 
00318   return false;
00319 }
00320 
00322 struct BuildRoadToolbarWindow : Window {
00323   int last_started_action; 
00324 
00325   BuildRoadToolbarWindow(const WindowDesc *desc, WindowNumber window_number) : Window()
00326   {
00327     this->InitNested(desc, window_number);
00328     this->SetWidgetsDisabledState(true,
00329         RTW_REMOVE,
00330         RTW_ONE_WAY,
00331         WIDGET_LIST_END);
00332 
00333     this->OnInvalidateData();
00334     this->last_started_action = WIDGET_LIST_END;
00335 
00336     if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
00337   }
00338 
00339   ~BuildRoadToolbarWindow()
00340   {
00341     if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false);
00342   }
00343 
00349   virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
00350   {
00351     if (!gui_scope) return;
00352     this->SetWidgetsDisabledState(!CanBuildVehicleInfrastructure(VEH_ROAD),
00353         RTW_DEPOT,
00354         RTW_BUS_STATION,
00355         RTW_TRUCK_STATION,
00356         WIDGET_LIST_END);
00357   }
00358 
00364   void UpdateOptionWidgetStatus(RoadToolbarWidgets clicked_widget)
00365   {
00366     /* The remove and the one way button state is driven
00367      * by the other buttons so they don't act on themselfs.
00368      * Both are only valid if they are able to apply as options. */
00369     switch (clicked_widget) {
00370       case RTW_REMOVE:
00371         this->RaiseWidget(RTW_ONE_WAY);
00372         this->SetWidgetDirty(RTW_ONE_WAY);
00373         break;
00374 
00375       case RTW_ONE_WAY:
00376         this->RaiseWidget(RTW_REMOVE);
00377         this->SetWidgetDirty(RTW_REMOVE);
00378         break;
00379 
00380       case RTW_BUS_STATION:
00381       case RTW_TRUCK_STATION:
00382         this->DisableWidget(RTW_ONE_WAY);
00383         this->SetWidgetDisabledState(RTW_REMOVE, !this->IsWidgetLowered(clicked_widget));
00384         break;
00385 
00386       case RTW_ROAD_X:
00387       case RTW_ROAD_Y:
00388       case RTW_AUTOROAD:
00389         this->SetWidgetsDisabledState(!this->IsWidgetLowered(clicked_widget),
00390             RTW_REMOVE,
00391             RTW_ONE_WAY,
00392             WIDGET_LIST_END);
00393         break;
00394 
00395       default:
00396         /* When any other buttons than road/station, raise and
00397          * disable the removal button */
00398         this->SetWidgetsDisabledState(true,
00399             RTW_REMOVE,
00400             RTW_ONE_WAY,
00401             WIDGET_LIST_END);
00402         this->SetWidgetsLoweredState(false,
00403             RTW_REMOVE,
00404             RTW_ONE_WAY,
00405             WIDGET_LIST_END);
00406         break;
00407     }
00408   }
00409 
00410   virtual void OnClick(Point pt, int widget, int click_count)
00411   {
00412     _remove_button_clicked = false;
00413     _one_way_button_clicked = false;
00414     switch (widget) {
00415       case RTW_ROAD_X:
00416         HandlePlacePushButton(this, RTW_ROAD_X, _road_type_infos[_cur_roadtype].cursor_nwse, HT_RECT);
00417         this->last_started_action = widget;
00418         break;
00419 
00420       case RTW_ROAD_Y:
00421         HandlePlacePushButton(this, RTW_ROAD_Y, _road_type_infos[_cur_roadtype].cursor_nesw, HT_RECT);
00422         this->last_started_action = widget;
00423         break;
00424 
00425       case RTW_AUTOROAD:
00426         HandlePlacePushButton(this, RTW_AUTOROAD, _road_type_infos[_cur_roadtype].cursor_autoroad, HT_RECT);
00427         this->last_started_action = widget;
00428         break;
00429 
00430       case RTW_DEMOLISH:
00431         HandlePlacePushButton(this, RTW_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL);
00432         this->last_started_action = widget;
00433         break;
00434 
00435       case RTW_DEPOT:
00436         if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD)) return;
00437         if (HandlePlacePushButton(this, RTW_DEPOT, SPR_CURSOR_ROAD_DEPOT, HT_RECT)) {
00438           ShowRoadDepotPicker(this);
00439           this->last_started_action = widget;
00440         }
00441         break;
00442 
00443       case RTW_BUS_STATION:
00444         if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD)) return;
00445         if (HandlePlacePushButton(this, RTW_BUS_STATION, SPR_CURSOR_BUS_STATION, HT_RECT)) {
00446           ShowRVStationPicker(this, ROADSTOP_BUS);
00447           this->last_started_action = widget;
00448         }
00449         break;
00450 
00451       case RTW_TRUCK_STATION:
00452         if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD)) return;
00453         if (HandlePlacePushButton(this, RTW_TRUCK_STATION, SPR_CURSOR_TRUCK_STATION, HT_RECT)) {
00454           ShowRVStationPicker(this, ROADSTOP_TRUCK);
00455           this->last_started_action = widget;
00456         }
00457         break;
00458 
00459       case RTW_ONE_WAY:
00460         if (this->IsWidgetDisabled(RTW_ONE_WAY)) return;
00461         this->SetDirty();
00462         this->ToggleWidgetLoweredState(RTW_ONE_WAY);
00463         SetSelectionRed(false);
00464         break;
00465 
00466       case RTW_BUILD_BRIDGE:
00467         HandlePlacePushButton(this, RTW_BUILD_BRIDGE, SPR_CURSOR_BRIDGE, HT_RECT);
00468         this->last_started_action = widget;
00469         break;
00470 
00471       case RTW_BUILD_TUNNEL:
00472         HandlePlacePushButton(this, RTW_BUILD_TUNNEL, SPR_CURSOR_ROAD_TUNNEL, HT_SPECIAL);
00473         this->last_started_action = widget;
00474         break;
00475 
00476       case RTW_REMOVE:
00477         if (this->IsWidgetDisabled(RTW_REMOVE)) return;
00478 
00479         DeleteWindowById(WC_SELECT_STATION, 0);
00480         ToggleRoadButton_Remove(this);
00481         SndPlayFx(SND_15_BEEP);
00482         break;
00483 
00484       default: NOT_REACHED();
00485     }
00486     this->UpdateOptionWidgetStatus((RoadToolbarWidgets)widget);
00487     if (_ctrl_pressed) RoadToolbar_CtrlChanged(this);
00488   }
00489 
00490   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
00491   {
00492     int num = CheckHotkeyMatch(roadtoolbar_hotkeys, keycode, this);
00493     if (num == -1 || this->GetWidget<NWidgetBase>(num) == NULL) return ES_NOT_HANDLED;
00494     this->OnClick(Point(), num, 1);
00495     MarkTileDirtyByTile(TileVirtXY(_thd.pos.x, _thd.pos.y)); // redraw tile selection
00496     return ES_HANDLED;
00497   }
00498 
00499   virtual void OnPlaceObject(Point pt, TileIndex tile)
00500   {
00501     _remove_button_clicked = this->IsWidgetLowered(RTW_REMOVE);
00502     _one_way_button_clicked = this->IsWidgetLowered(RTW_ONE_WAY);
00503     switch (this->last_started_action) {
00504       case RTW_ROAD_X:
00505         _place_road_flag = RF_DIR_X;
00506         if (_tile_fract_coords.x >= 8) _place_road_flag |= RF_START_HALFROAD_X;
00507         VpStartPlaceSizing(tile, VPM_FIX_Y, DDSP_PLACE_ROAD_X_DIR);
00508         break;
00509 
00510       case RTW_ROAD_Y:
00511         _place_road_flag = RF_DIR_Y;
00512         if (_tile_fract_coords.y >= 8) _place_road_flag |= RF_START_HALFROAD_Y;
00513         VpStartPlaceSizing(tile, VPM_FIX_X, DDSP_PLACE_ROAD_Y_DIR);
00514         break;
00515 
00516       case RTW_AUTOROAD:
00517         _place_road_flag = RF_NONE;
00518         if (_tile_fract_coords.x >= 8) _place_road_flag |= RF_START_HALFROAD_X;
00519         if (_tile_fract_coords.y >= 8) _place_road_flag |= RF_START_HALFROAD_Y;
00520         VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_PLACE_AUTOROAD);
00521         break;
00522 
00523       case RTW_DEMOLISH:
00524         PlaceProc_DemolishArea(tile);
00525         break;
00526 
00527       case RTW_DEPOT:
00528         DoCommandP(tile, _cur_roadtype << 2 | _road_depot_orientation, 0,
00529             CMD_BUILD_ROAD_DEPOT | CMD_MSG(_road_type_infos[_cur_roadtype].err_depot), CcRoadDepot);
00530         break;
00531 
00532       case RTW_BUS_STATION:
00533         PlaceRoad_BusStation(tile);
00534         break;
00535 
00536       case RTW_TRUCK_STATION:
00537         PlaceRoad_TruckStation(tile);
00538         break;
00539 
00540       case RTW_BUILD_BRIDGE:
00541         PlaceRoad_Bridge(tile, this);
00542         break;
00543 
00544       case RTW_BUILD_TUNNEL:
00545         DoCommandP(tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), 0,
00546             CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRoadTunnel);
00547         break;
00548 
00549       default: NOT_REACHED();
00550     }
00551   }
00552 
00553   virtual void OnPlaceObjectAbort()
00554   {
00555     this->RaiseButtons();
00556     this->SetWidgetsDisabledState(true,
00557         RTW_REMOVE,
00558         RTW_ONE_WAY,
00559         WIDGET_LIST_END);
00560     this->SetWidgetDirty(RTW_REMOVE);
00561     this->SetWidgetDirty(RTW_ONE_WAY);
00562 
00563     DeleteWindowById(WC_BUS_STATION, TRANSPORT_ROAD);
00564     DeleteWindowById(WC_TRUCK_STATION, TRANSPORT_ROAD);
00565     DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_ROAD);
00566     DeleteWindowById(WC_SELECT_STATION, 0);
00567     DeleteWindowByClass(WC_BUILD_BRIDGE);
00568   }
00569 
00570   virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
00571   {
00572     /* Here we update the end tile flags
00573      * of the road placement actions.
00574      * At first we reset the end halfroad
00575      * bits and if needed we set them again. */
00576     switch (select_proc) {
00577       case DDSP_PLACE_ROAD_X_DIR:
00578         _place_road_flag &= ~RF_END_HALFROAD_X;
00579         if (pt.x & 8) _place_road_flag |= RF_END_HALFROAD_X;
00580         break;
00581 
00582       case DDSP_PLACE_ROAD_Y_DIR:
00583         _place_road_flag &= ~RF_END_HALFROAD_Y;
00584         if (pt.y & 8) _place_road_flag |= RF_END_HALFROAD_Y;
00585         break;
00586 
00587       case DDSP_PLACE_AUTOROAD:
00588         _place_road_flag &= ~(RF_END_HALFROAD_Y | RF_END_HALFROAD_X);
00589         if (pt.y & 8) _place_road_flag |= RF_END_HALFROAD_Y;
00590         if (pt.x & 8) _place_road_flag |= RF_END_HALFROAD_X;
00591 
00592         /* For autoroad we need to update the
00593          * direction of the road */
00594         if (_thd.size.x > _thd.size.y || (_thd.size.x == _thd.size.y &&
00595             ( (_tile_fract_coords.x < _tile_fract_coords.y && (_tile_fract_coords.x + _tile_fract_coords.y) < 16) ||
00596             (_tile_fract_coords.x > _tile_fract_coords.y && (_tile_fract_coords.x + _tile_fract_coords.y) > 16) ))) {
00597           /* Set dir = X */
00598           _place_road_flag &= ~RF_DIR_Y;
00599         } else {
00600           /* Set dir = Y */
00601           _place_road_flag |= RF_DIR_Y;
00602         }
00603 
00604         break;
00605 
00606       default:
00607         break;
00608     }
00609 
00610     VpSelectTilesWithMethod(pt.x, pt.y, select_method);
00611   }
00612 
00613   virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
00614   {
00615     if (pt.x != -1) {
00616       switch (select_proc) {
00617         default: NOT_REACHED();
00618         case DDSP_BUILD_BRIDGE:
00619           if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
00620           ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, RoadTypeToRoadTypes(_cur_roadtype));
00621           break;
00622 
00623         case DDSP_DEMOLISH_AREA:
00624           GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
00625           break;
00626 
00627         case DDSP_PLACE_ROAD_X_DIR:
00628         case DDSP_PLACE_ROAD_Y_DIR:
00629         case DDSP_PLACE_AUTOROAD:
00630           /* Flag description:
00631            * Use the first three bits (0x07) if dir == Y
00632            * else use the last 2 bits (X dir has
00633            * not the 3rd bit set) */
00634           _place_road_flag = (RoadFlags)((_place_road_flag & RF_DIR_Y) ? (_place_road_flag & 0x07) : (_place_road_flag >> 3));
00635 
00636           DoCommandP(start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 5),
00637               _remove_button_clicked ?
00638               CMD_REMOVE_LONG_ROAD | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_road) :
00639               CMD_BUILD_LONG_ROAD | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_road), CcPlaySound1D);
00640           break;
00641 
00642         case DDSP_BUILD_BUSSTOP:
00643           PlaceRoadStop(start_tile, end_tile, (_ctrl_pressed << 5) | RoadTypeToRoadTypes(_cur_roadtype) << 2 | ROADSTOP_BUS, CMD_BUILD_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_station[ROADSTOP_BUS]));
00644           break;
00645 
00646         case DDSP_BUILD_TRUCKSTOP:
00647           PlaceRoadStop(start_tile, end_tile, (_ctrl_pressed << 5) | RoadTypeToRoadTypes(_cur_roadtype) << 2 | ROADSTOP_TRUCK, CMD_BUILD_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_station[ROADSTOP_TRUCK]));
00648           break;
00649 
00650         case DDSP_REMOVE_BUSSTOP: {
00651           TileArea ta(start_tile, end_tile);
00652           DoCommandP(ta.tile, ta.w | ta.h << 8, ROADSTOP_BUS, CMD_REMOVE_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_station[ROADSTOP_BUS]), CcPlaySound1D);
00653           break;
00654         }
00655 
00656         case DDSP_REMOVE_TRUCKSTOP: {
00657           TileArea ta(start_tile, end_tile);
00658           DoCommandP(ta.tile, ta.w | ta.h << 8, ROADSTOP_TRUCK, CMD_REMOVE_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_station[ROADSTOP_TRUCK]), CcPlaySound1D);
00659           break;
00660         }
00661       }
00662     }
00663   }
00664 
00665   virtual void OnPlacePresize(Point pt, TileIndex tile)
00666   {
00667     DoCommand(tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), 0, DC_AUTO, CMD_BUILD_TUNNEL);
00668     VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
00669   }
00670 
00671   virtual EventState OnCTRLStateChange()
00672   {
00673     if (RoadToolbar_CtrlChanged(this)) return ES_HANDLED;
00674     return ES_NOT_HANDLED;
00675   }
00676 
00677   static Hotkey<BuildRoadToolbarWindow> roadtoolbar_hotkeys[];
00678 };
00679 
00680 Hotkey<BuildRoadToolbarWindow> BuildRoadToolbarWindow::roadtoolbar_hotkeys[] = {
00681   Hotkey<BuildRoadToolbarWindow>('1', "build_x", RTW_ROAD_X),
00682   Hotkey<BuildRoadToolbarWindow>('2', "build_y", RTW_ROAD_Y),
00683   Hotkey<BuildRoadToolbarWindow>('3', "autoroad", RTW_AUTOROAD),
00684   Hotkey<BuildRoadToolbarWindow>('4', "demolish", RTW_DEMOLISH),
00685   Hotkey<BuildRoadToolbarWindow>('5', "depot", RTW_DEPOT),
00686   Hotkey<BuildRoadToolbarWindow>('6', "bus_station", RTW_BUS_STATION),
00687   Hotkey<BuildRoadToolbarWindow>('7', "truck_station", RTW_TRUCK_STATION),
00688   Hotkey<BuildRoadToolbarWindow>('8', "oneway", RTW_ONE_WAY),
00689   Hotkey<BuildRoadToolbarWindow>('B', "bridge", RTW_BUILD_BRIDGE),
00690   Hotkey<BuildRoadToolbarWindow>('T', "tunnel", RTW_BUILD_TUNNEL),
00691   Hotkey<BuildRoadToolbarWindow>('R', "remove", RTW_REMOVE),
00692   HOTKEY_LIST_END(BuildRoadToolbarWindow)
00693 };
00694 Hotkey<BuildRoadToolbarWindow> *_roadtoolbar_hotkeys = BuildRoadToolbarWindow::roadtoolbar_hotkeys;
00695 
00696 
00697 static const NWidgetPart _nested_build_road_widgets[] = {
00698   NWidget(NWID_HORIZONTAL),
00699     NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
00700     NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00701     NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
00702   EndContainer(),
00703   NWidget(NWID_HORIZONTAL),
00704     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_ROAD_X),
00705             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_X_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION),
00706     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_ROAD_Y),
00707             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_Y_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION),
00708     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_AUTOROAD),
00709             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOROAD, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD),
00710     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_DEMOLISH),
00711             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
00712     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_DEPOT),
00713             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_DEPOT, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT),
00714     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUS_STATION),
00715             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_BUS_STATION, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION),
00716     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_TRUCK_STATION),
00717             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRUCK_BAY, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY),
00718     NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
00719     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_ONE_WAY),
00720             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_ONE_WAY, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD),
00721     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_BRIDGE),
00722             SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE),
00723     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_TUNNEL),
00724             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL),
00725     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_REMOVE),
00726             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD),
00727   EndContainer(),
00728 };
00729 
00730 static const WindowDesc _build_road_desc(
00731   WDP_ALIGN_TOOLBAR, 0, 0,
00732   WC_BUILD_TOOLBAR, WC_NONE,
00733   WDF_CONSTRUCTION,
00734   _nested_build_road_widgets, lengthof(_nested_build_road_widgets)
00735 );
00736 
00737 static const NWidgetPart _nested_build_tramway_widgets[] = {
00738   NWidget(NWID_HORIZONTAL),
00739     NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
00740     NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00741     NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
00742   EndContainer(),
00743   NWidget(NWID_HORIZONTAL),
00744     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_ROAD_X),
00745             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRAMWAY_X_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION),
00746     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_ROAD_Y),
00747             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRAMWAY_Y_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION),
00748     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_AUTOROAD),
00749             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOTRAM, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM),
00750     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_DEMOLISH),
00751             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
00752     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_DEPOT),
00753             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_DEPOT, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT),
00754     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUS_STATION),
00755             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_BUS_STATION, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION),
00756     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_TRUCK_STATION),
00757             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRUCK_BAY, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION),
00758     NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
00759     NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, RTW_ONE_WAY), SetMinimalSize(0, 0),
00760     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_BRIDGE),
00761             SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE),
00762     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_TUNNEL),
00763             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL),
00764     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_REMOVE),
00765             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS),
00766   EndContainer(),
00767 };
00768 
00769 static const WindowDesc _build_tramway_desc(
00770   WDP_ALIGN_TOOLBAR, 0, 0,
00771   WC_BUILD_TOOLBAR, WC_NONE,
00772   WDF_CONSTRUCTION,
00773   _nested_build_tramway_widgets, lengthof(_nested_build_tramway_widgets)
00774 );
00775 
00783 Window *ShowBuildRoadToolbar(RoadType roadtype)
00784 {
00785   if (!Company::IsValidID(_local_company)) return NULL;
00786   _cur_roadtype = roadtype;
00787 
00788   DeleteWindowByClass(WC_BUILD_TOOLBAR);
00789   return AllocateWindowDescFront<BuildRoadToolbarWindow>(roadtype == ROADTYPE_ROAD ? &_build_road_desc : &_build_tramway_desc, TRANSPORT_ROAD);
00790 }
00791 
00792 EventState RoadToolbarGlobalHotkeys(uint16 key, uint16 keycode)
00793 {
00794   extern RoadType _last_built_roadtype;
00795   int num = CheckHotkeyMatch<BuildRoadToolbarWindow>(_roadtoolbar_hotkeys, keycode, NULL, true);
00796   if (num == -1) return ES_NOT_HANDLED;
00797   Window *w = ShowBuildRoadToolbar(_last_built_roadtype);
00798   if (w == NULL) return ES_NOT_HANDLED;
00799   return w->OnKeyPress(key, keycode);
00800 }
00801 
00802 static const NWidgetPart _nested_build_road_scen_widgets[] = {
00803   NWidget(NWID_HORIZONTAL),
00804     NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
00805     NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00806     NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
00807   EndContainer(),
00808   NWidget(NWID_HORIZONTAL),
00809     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_ROAD_X),
00810             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_X_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION),
00811     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_ROAD_Y),
00812             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_Y_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION),
00813     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_AUTOROAD),
00814             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOROAD, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD),
00815     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_DEMOLISH),
00816             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
00817     NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
00818     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_ONE_WAY),
00819             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_ONE_WAY, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD),
00820     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_BRIDGE),
00821             SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE),
00822     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_BUILD_TUNNEL),
00823             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL),
00824     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, RTW_REMOVE),
00825             SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD),
00826   EndContainer(),
00827 };
00828 
00829 static const WindowDesc _build_road_scen_desc(
00830   WDP_AUTO, 0, 0,
00831   WC_SCEN_BUILD_TOOLBAR, WC_NONE,
00832   WDF_CONSTRUCTION,
00833   _nested_build_road_scen_widgets, lengthof(_nested_build_road_scen_widgets)
00834 );
00835 
00840 Window *ShowBuildRoadScenToolbar()
00841 {
00842   _cur_roadtype = ROADTYPE_ROAD;
00843   return AllocateWindowDescFront<BuildRoadToolbarWindow>(&_build_road_scen_desc, 0);
00844 }
00845 
00846 EventState RoadToolbarEditorGlobalHotkeys(uint16 key, uint16 keycode)
00847 {
00848   int num = CheckHotkeyMatch<BuildRoadToolbarWindow>(_roadtoolbar_hotkeys, keycode, NULL, true);
00849   if (num == -1) return ES_NOT_HANDLED;
00850   Window *w = ShowBuildRoadScenToolbar();
00851   if (w == NULL) return ES_NOT_HANDLED;
00852   return w->OnKeyPress(key, keycode);
00853 }
00854 
00856 enum BuildRoadDepotWidgets {
00857   BRDW_CAPTION,
00858   BRDW_DEPOT_NE,
00859   BRDW_DEPOT_SE,
00860   BRDW_DEPOT_SW,
00861   BRDW_DEPOT_NW,
00862 };
00863 
00864 struct BuildRoadDepotWindow : public PickerWindowBase {
00865   BuildRoadDepotWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(parent)
00866   {
00867     this->CreateNestedTree(desc);
00868 
00869     this->LowerWidget(_road_depot_orientation + BRDW_DEPOT_NE);
00870     if ( _cur_roadtype == ROADTYPE_TRAM) {
00871       this->GetWidget<NWidgetCore>(BRDW_CAPTION)->widget_data = STR_BUILD_DEPOT_TRAM_ORIENTATION_CAPTION;
00872       for (int i = BRDW_DEPOT_NE; i <= BRDW_DEPOT_NW; i++) this->GetWidget<NWidgetCore>(i)->tool_tip = STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP;
00873     }
00874 
00875     this->FinishInitNested(desc, TRANSPORT_ROAD);
00876   }
00877 
00878   virtual void DrawWidget(const Rect &r, int widget) const
00879   {
00880     if (!IsInsideMM(widget, BRDW_DEPOT_NE, BRDW_DEPOT_NW + 1)) return;
00881 
00882     DrawRoadDepotSprite(r.left - 1, r.top, (DiagDirection)(widget - BRDW_DEPOT_NE + DIAGDIR_NE), _cur_roadtype);
00883   }
00884 
00885   virtual void OnClick(Point pt, int widget, int click_count)
00886   {
00887     switch (widget) {
00888       case BRDW_DEPOT_NW:
00889       case BRDW_DEPOT_NE:
00890       case BRDW_DEPOT_SW:
00891       case BRDW_DEPOT_SE:
00892         this->RaiseWidget(_road_depot_orientation + BRDW_DEPOT_NE);
00893         _road_depot_orientation = (DiagDirection)(widget - BRDW_DEPOT_NE);
00894         this->LowerWidget(_road_depot_orientation + BRDW_DEPOT_NE);
00895         SndPlayFx(SND_15_BEEP);
00896         this->SetDirty();
00897         break;
00898 
00899       default:
00900         break;
00901     }
00902   }
00903 };
00904 
00905 static const NWidgetPart _nested_build_road_depot_widgets[] = {
00906   NWidget(NWID_HORIZONTAL),
00907     NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
00908     NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, BRDW_CAPTION), SetDataTip(STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00909   EndContainer(),
00910   NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
00911     NWidget(NWID_SPACER), SetMinimalSize(0, 3),
00912     NWidget(NWID_HORIZONTAL_LTR),
00913       NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
00914       NWidget(NWID_VERTICAL),
00915         NWidget(WWT_PANEL, COLOUR_GREY, BRDW_DEPOT_NW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
00916         EndContainer(),
00917         NWidget(NWID_SPACER), SetMinimalSize(0, 2),
00918         NWidget(WWT_PANEL, COLOUR_GREY, BRDW_DEPOT_SW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
00919         EndContainer(),
00920       EndContainer(),
00921       NWidget(NWID_SPACER), SetMinimalSize(2, 0),
00922       NWidget(NWID_VERTICAL),
00923         NWidget(WWT_PANEL, COLOUR_GREY, BRDW_DEPOT_NE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
00924         EndContainer(),
00925         NWidget(NWID_SPACER), SetMinimalSize(0, 2),
00926         NWidget(WWT_PANEL, COLOUR_GREY, BRDW_DEPOT_SE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
00927         EndContainer(),
00928       EndContainer(),
00929       NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
00930     EndContainer(),
00931     NWidget(NWID_SPACER), SetMinimalSize(0, 3),
00932   EndContainer(),
00933 };
00934 
00935 static const WindowDesc _build_road_depot_desc(
00936   WDP_AUTO, 0, 0,
00937   WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
00938   WDF_CONSTRUCTION,
00939   _nested_build_road_depot_widgets, lengthof(_nested_build_road_depot_widgets)
00940 );
00941 
00942 static void ShowRoadDepotPicker(Window *parent)
00943 {
00944   new BuildRoadDepotWindow(&_build_road_depot_desc, parent);
00945 }
00946 
00948 enum BuildRoadStationWidgets {
00949   BRSW_CAPTION,
00950   BRSW_BACKGROUND,
00951   BRSW_STATION_NE,
00952   BRSW_STATION_SE,
00953   BRSW_STATION_SW,
00954   BRSW_STATION_NW,
00955   BRSW_STATION_X,
00956   BRSW_STATION_Y,
00957   BRSW_LT_OFF,
00958   BRSW_LT_ON,
00959   BRSW_INFO,
00960 };
00961 
00962 struct BuildRoadStationWindow : public PickerWindowBase {
00963   BuildRoadStationWindow(const WindowDesc *desc, Window *parent, RoadStopType rs) : PickerWindowBase(parent)
00964   {
00965     this->CreateNestedTree(desc);
00966 
00967     /* Trams don't have non-drivethrough stations */
00968     if (_cur_roadtype == ROADTYPE_TRAM && _road_station_picker_orientation < DIAGDIR_END) {
00969       _road_station_picker_orientation = DIAGDIR_END;
00970     }
00971     this->SetWidgetsDisabledState(_cur_roadtype == ROADTYPE_TRAM,
00972         BRSW_STATION_NE,
00973         BRSW_STATION_SE,
00974         BRSW_STATION_SW,
00975         BRSW_STATION_NW,
00976         WIDGET_LIST_END);
00977 
00978     this->GetWidget<NWidgetCore>(BRSW_CAPTION)->widget_data = _road_type_infos[_cur_roadtype].picker_title[rs];
00979     for (uint i = BRSW_STATION_NE; i < BRSW_LT_OFF; i++) this->GetWidget<NWidgetCore>(i)->tool_tip = _road_type_infos[_cur_roadtype].picker_tooltip[rs];
00980 
00981     this->LowerWidget(_road_station_picker_orientation + BRSW_STATION_NE);
00982     this->LowerWidget(_settings_client.gui.station_show_coverage + BRSW_LT_OFF);
00983 
00984     this->FinishInitNested(desc, TRANSPORT_ROAD);
00985 
00986     this->window_class = (rs == ROADSTOP_BUS) ? WC_BUS_STATION : WC_TRUCK_STATION;
00987   }
00988 
00989   virtual ~BuildRoadStationWindow()
00990   {
00991     DeleteWindowById(WC_SELECT_STATION, 0);
00992   }
00993 
00994   virtual void OnPaint()
00995   {
00996     this->DrawWidgets();
00997 
00998     int rad = _settings_game.station.modified_catchment ? CA_TRUCK /* = CA_BUS */ : CA_UNMODIFIED;
00999     if (_settings_client.gui.station_show_coverage) {
01000       SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
01001     } else {
01002       SetTileSelectSize(1, 1);
01003     }
01004 
01005     /* 'Accepts' and 'Supplies' texts. */
01006     StationCoverageType sct = (this->window_class == WC_BUS_STATION) ? SCT_PASSENGERS_ONLY : SCT_NON_PASSENGERS_ONLY;
01007     int top = this->GetWidget<NWidgetBase>(BRSW_LT_ON)->pos_y + this->GetWidget<NWidgetBase>(BRSW_LT_ON)->current_y + WD_PAR_VSEP_NORMAL;
01008     NWidgetBase *back_nwi = this->GetWidget<NWidgetBase>(BRSW_BACKGROUND);
01009     int right = back_nwi->pos_x +  back_nwi->current_x;
01010     int bottom = back_nwi->pos_y +  back_nwi->current_y;
01011     top = DrawStationCoverageAreaText(back_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, sct, rad, false) + WD_PAR_VSEP_NORMAL;
01012     top = DrawStationCoverageAreaText(back_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, sct, rad, true) + WD_PAR_VSEP_NORMAL;
01013     /* Resize background if the text is not equally long as the window. */
01014     if (top > bottom || (top < bottom && back_nwi->current_y > back_nwi->smallest_y)) {
01015       ResizeWindow(this, 0, top - bottom);
01016     }
01017   }
01018 
01019   virtual void DrawWidget(const Rect &r, int widget) const
01020   {
01021     if (!IsInsideMM(widget, BRSW_STATION_NE, BRSW_STATION_Y + 1)) return;
01022 
01023     StationType st = (this->window_class == WC_BUS_STATION) ? STATION_BUS : STATION_TRUCK;
01024     StationPickerDrawSprite(r.left + TILE_PIXELS, r.bottom - TILE_PIXELS, st, INVALID_RAILTYPE, widget < BRSW_STATION_X ? ROADTYPE_ROAD : _cur_roadtype, widget - BRSW_STATION_NE);
01025   }
01026 
01027   virtual void OnClick(Point pt, int widget, int click_count)
01028   {
01029     switch (widget) {
01030       case BRSW_STATION_NE:
01031       case BRSW_STATION_SE:
01032       case BRSW_STATION_SW:
01033       case BRSW_STATION_NW:
01034       case BRSW_STATION_X:
01035       case BRSW_STATION_Y:
01036         this->RaiseWidget(_road_station_picker_orientation + BRSW_STATION_NE);
01037         _road_station_picker_orientation = (DiagDirection)(widget - BRSW_STATION_NE);
01038         this->LowerWidget(_road_station_picker_orientation + BRSW_STATION_NE);
01039         SndPlayFx(SND_15_BEEP);
01040         this->SetDirty();
01041         DeleteWindowById(WC_SELECT_STATION, 0);
01042         break;
01043 
01044       case BRSW_LT_OFF:
01045       case BRSW_LT_ON:
01046         this->RaiseWidget(_settings_client.gui.station_show_coverage + BRSW_LT_OFF);
01047         _settings_client.gui.station_show_coverage = (widget != BRSW_LT_OFF);
01048         this->LowerWidget(_settings_client.gui.station_show_coverage + BRSW_LT_OFF);
01049         SndPlayFx(SND_15_BEEP);
01050         this->SetDirty();
01051         break;
01052 
01053       default:
01054         break;
01055     }
01056   }
01057 
01058   virtual void OnTick()
01059   {
01060     CheckRedrawStationCoverage(this);
01061   }
01062 };
01063 
01065 static const NWidgetPart _nested_rv_station_picker_widgets[] = {
01066   NWidget(NWID_HORIZONTAL),
01067     NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
01068     NWidget(WWT_CAPTION,  COLOUR_DARK_GREEN, BRSW_CAPTION),
01069   EndContainer(),
01070   NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BRSW_BACKGROUND),
01071     NWidget(NWID_SPACER), SetMinimalSize(0, 3),
01072     NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0),
01073       NWidget(NWID_SPACER), SetFill(1, 0),
01074       NWidget(WWT_PANEL, COLOUR_GREY, BRSW_STATION_NW), SetMinimalSize(66, 50), EndContainer(),
01075       NWidget(WWT_PANEL, COLOUR_GREY, BRSW_STATION_NE), SetMinimalSize(66, 50), EndContainer(),
01076       NWidget(WWT_PANEL, COLOUR_GREY, BRSW_STATION_X),  SetMinimalSize(66, 50), EndContainer(),
01077       NWidget(NWID_SPACER), SetFill(1, 0),
01078     EndContainer(),
01079     NWidget(NWID_SPACER), SetMinimalSize(0, 2),
01080     NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0),
01081       NWidget(NWID_SPACER), SetFill(1, 0),
01082       NWidget(WWT_PANEL, COLOUR_GREY, BRSW_STATION_SW), SetMinimalSize(66, 50), EndContainer(),
01083       NWidget(WWT_PANEL, COLOUR_GREY, BRSW_STATION_SE), SetMinimalSize(66, 50), EndContainer(),
01084       NWidget(WWT_PANEL, COLOUR_GREY, BRSW_STATION_Y),  SetMinimalSize(66, 50), EndContainer(),
01085       NWidget(NWID_SPACER), SetFill(1, 0),
01086     EndContainer(),
01087     NWidget(NWID_SPACER), SetMinimalSize(0, 1),
01088     NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
01089       NWidget(WWT_LABEL, COLOUR_DARK_GREEN, BRSW_INFO), SetMinimalSize(140, 14), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL),
01090       NWidget(NWID_SPACER), SetFill(1, 0),
01091     EndContainer(),
01092     NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
01093       NWidget(NWID_SPACER), SetFill(1, 0),
01094       NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_LT_OFF), SetMinimalSize(60, 12),
01095                       SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
01096       NWidget(WWT_TEXTBTN, COLOUR_GREY, BRSW_LT_ON), SetMinimalSize(60, 12),
01097                       SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
01098       NWidget(NWID_SPACER), SetFill(1, 0),
01099     EndContainer(),
01100     NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetResize(0, 1),
01101   EndContainer(),
01102 };
01103 
01104 static const WindowDesc _rv_station_picker_desc(
01105   WDP_AUTO, 0, 0,
01106   WC_BUS_STATION, WC_BUILD_TOOLBAR,
01107   WDF_CONSTRUCTION,
01108   _nested_rv_station_picker_widgets, lengthof(_nested_rv_station_picker_widgets)
01109 );
01110 
01111 static void ShowRVStationPicker(Window *parent, RoadStopType rs)
01112 {
01113   new BuildRoadStationWindow(&_rv_station_picker_desc, parent, rs);
01114 }
01115 
01116 void InitializeRoadGui()
01117 {
01118   _road_depot_orientation = DIAGDIR_NW;
01119   _road_station_picker_orientation = DIAGDIR_NW;
01120 }

Generated on Fri May 27 04:19:47 2011 for OpenTTD by  doxygen 1.6.1