road_gui.cpp

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

Generated on Thu Jan 20 22:57:39 2011 for OpenTTD by  doxygen 1.6.1