# airport_gui.cpp

Go to the documentation of this file.

    00001 /* $Id: airport_gui.cpp 18809 2010-01-15 16:41:15Z rubidium $ */
    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 "window_gui.h"
    00014 #include "station_gui.h"
    00015 #include "terraform_gui.h"
    00016 #include "airport.h"
    00017 #include "sound_func.h"
    00018 #include "window_func.h"
    00019 #include "strings_func.h"
    00020 #include "viewport_func.h"
    00021 #include "gfx_func.h"
    00022 #include "company_func.h"
    00023 #include "tilehighlight_func.h"
    00024 #include "company_base.h"
    00025 #include "station_type.h"
    00026
    00027 #include "table/sprites.h"
    00028 #include "table/strings.h"
    00029
    00030 static byte _selected_airport_type;
    00031
    00032 static void ShowBuildAirportPicker(Window *parent);
    00033
    00034
    00035 void CcBuildAirport(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
    00036 {
    00037   if (result.Failed()) return;
    00038
    00039   SndPlayTileFx(SND_1F_SPLAT, tile);
    00040   if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
    00041 }
    00042
    00043 static void PlaceAirport(TileIndex tile)
    00044 {
    00045   uint32 p2 = _ctrl_pressed;
    00046   SB(p2, 16, 16, INVALID_STATION); // no station to join
    00047
    00048   CommandContainer cmdcont = { tile, _selected_airport_type, p2, CMD_BUILD_AIRPORT | CMD_MSG(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE), CcBuildAirport, "" };
    00049   ShowSelectStationIfNeeded(cmdcont, TileArea(tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE));
    00050 }
    00051
    00053 enum {
    00054   ATW_AIRPORT,
    00055   ATW_DEMOLISH,
    00056 };
    00057
    00058
    00059 static void BuildAirClick_Airport(Window *w)
    00060 {
    00061   if (HandlePlacePushButton(w, ATW_AIRPORT, SPR_CURSOR_AIRPORT, HT_RECT, PlaceAirport)) ShowBuildAirportPicker(w);
    00062 }
    00063
    00064 static void BuildAirClick_Demolish(Window *w)
    00065 {
    00066   HandlePlacePushButton(w, ATW_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT, PlaceProc_DemolishArea);
    00067 }
    00068
    00069
    00070 typedef void OnButtonClick(Window *w);
    00071 static OnButtonClick * const _build_air_button_proc[] = {
    00072   BuildAirClick_Airport,
    00073   BuildAirClick_Demolish,
    00074 };
    00075
    00076 struct BuildAirToolbarWindow : Window {
    00077   BuildAirToolbarWindow(const WindowDesc *desc, WindowNumber window_number) : Window()
    00078   {
    00079     this->InitNested(desc, window_number);
    00080     if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
    00081   }
    00082
    00083   ~BuildAirToolbarWindow()
    00084   {
    00085     if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false);
    00086   }
    00087
    00088   virtual void OnPaint()
    00089   {
    00090     this->DrawWidgets();
    00091   }
    00092
    00093   virtual void OnClick(Point pt, int widget)
    00094   {
    00095     if (!IsInsideBS(widget, ATW_AIRPORT, lengthof(_build_air_button_proc))) return;
    00096
    00097     _build_air_button_proc[widget - ATW_AIRPORT](this);
    00098   }
    00099
    00100
    00101   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
    00102   {
    00103     switch (keycode) {
    00104       case '1': BuildAirClick_Airport(this); break;
    00105       case '2': BuildAirClick_Demolish(this); break;
    00106       default: return ES_NOT_HANDLED;
    00107     }
    00108     return ES_HANDLED;
    00109   }
    00110
    00111   virtual void OnPlaceObject(Point pt, TileIndex tile)
    00112   {
    00113     _place_proc(tile);
    00114   }
    00115
    00116   virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
    00117   {
    00118     VpSelectTilesWithMethod(pt.x, pt.y, select_method);
    00119   }
    00120
    00121   virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
    00122   {
    00123     if (pt.x != -1 && select_proc == DDSP_DEMOLISH_AREA) {
    00124       GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
    00125     }
    00126   }
    00127
    00128   virtual void OnPlaceObjectAbort()
    00129   {
    00130     this->RaiseButtons();
    00131
    00132     DeleteWindowById(WC_BUILD_STATION, TRANSPORT_AIR);
    00133     DeleteWindowById(WC_SELECT_STATION, 0);
    00134   }
    00135 };
    00136
    00137 static const NWidgetPart _nested_air_toolbar_widgets[] = {
    00138   NWidget(NWID_HORIZONTAL),
    00139     NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
    00140     NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_TOOLBAR_AIRCRAFT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
    00141     NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
    00142   EndContainer(),
    00143   NWidget(NWID_HORIZONTAL),
    00144     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, ATW_AIRPORT), SetFill(0, 1), SetMinimalSize(42, 22), SetDataTip(SPR_IMG_AIRPORT, STR_TOOLBAR_AIRCRAFT_BUILD_AIRPORT_TOOLTIP),
    00145     NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetMinimalSize(4, 22), SetFill(1, 1), EndContainer(),
    00146     NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, ATW_DEMOLISH), SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
    00147   EndContainer(),
    00148 };
    00149
    00150 static const WindowDesc _air_toolbar_desc(
    00151   WDP_ALIGN_TOOLBAR, 0, 0,
    00152   WC_BUILD_TOOLBAR, WC_NONE,
    00153   WDF_CONSTRUCTION,
    00154   _nested_air_toolbar_widgets, lengthof(_nested_air_toolbar_widgets)
    00155 );
    00156
    00157 void ShowBuildAirToolbar()
    00158 {
    00159   if (!Company::IsValidID(_local_company)) return;
    00160
    00161   DeleteWindowByClass(WC_BUILD_TOOLBAR);
    00162   AllocateWindowDescFront<BuildAirToolbarWindow>(&_air_toolbar_desc, TRANSPORT_AIR);
    00163 }
    00164
    00166 enum AirportPickerWidgets {
    00167   /* Airport selection buttons. */
    00168   BAW_SMALL_AIRPORT,
    00169   BAW_CITY_AIRPORT,
    00170   BAW_HELIPORT,
    00171   BAW_METRO_AIRPORT,
    00172   BAW_INTERNATIONAL_AIRPORT,
    00173   BAW_COMMUTER_AIRPORT,
    00174   BAW_HELIDEPOT,
    00175   BAW_INTERCONTINENTAL_AIRPORT,
    00176   BAW_HELISTATION,
    00177
    00178   BAW_BOTTOMPANEL,
    00179   BAW_BTN_DONTHILIGHT,
    00180   BAW_BTN_DOHILIGHT,
    00181
    00182   BAW_LAST_AIRPORT = BAW_HELISTATION,
    00183   BAW_AIRPORT_COUNT = BAW_LAST_AIRPORT - BAW_SMALL_AIRPORT + 1,
    00184 };
    00185
    00186 class AirportPickerWindow : public PickerWindowBase {
    00187 public:
    00188   AirportPickerWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(parent)
    00189   {
    00190     this->InitNested(desc, TRANSPORT_AIR);
    00191     this->SetWidgetLoweredState(BAW_BTN_DONTHILIGHT, !_settings_client.gui.station_show_coverage);
    00192     this->SetWidgetLoweredState(BAW_BTN_DOHILIGHT, _settings_client.gui.station_show_coverage);
    00193     this->OnInvalidateData();
    00194     this->SelectOtherAirport(_selected_airport_type);
    00195   }
    00196
    00197   virtual ~AirportPickerWindow()
    00198   {
    00199     DeleteWindowById(WC_SELECT_STATION, 0);
    00200   }
    00201
    00202   virtual void OnPaint()
    00203   {
    00204     this->DrawWidgets();
    00205
    00206     const AirportSpec *as = AirportSpec::Get(_selected_airport_type);
    00207     int rad = _settings_game.station.modified_catchment ? as->catchment : (uint)CA_UNMODIFIED;
    00208
    00209     uint16 top = this->GetWidget<NWidgetBase>(BAW_BTN_DOHILIGHT)->pos_y + this->GetWidget<NWidgetBase>(BAW_BTN_DOHILIGHT)->current_y + WD_PAR_VSEP_NORMAL;
    00210     NWidgetBase *panel_nwi = this->GetWidget<NWidgetBase>(BAW_BOTTOMPANEL);
    00211     int right = panel_nwi->pos_x +  panel_nwi->current_x;
    00212     int bottom = panel_nwi->pos_y +  panel_nwi->current_y;
    00213     /* only show the station (airport) noise, if the noise option is activated */
    00214     if (_settings_game.economy.station_noise_level) {
    00215       /* show the noise of the selected airport */
    00216       SetDParam(0, as->noise_level);
    00217       DrawString(panel_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, STR_STATION_BUILD_NOISE);
    00218       top += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
    00219     }
    00220
    00221     /* strings such as 'Size' and 'Coverage Area' */
    00222     top = DrawStationCoverageAreaText(panel_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, SCT_ALL, rad, false) + WD_PAR_VSEP_NORMAL;
    00223     top = DrawStationCoverageAreaText(panel_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, SCT_ALL, rad, true) + WD_PAR_VSEP_NORMAL;
    00224     /* Resize background if the text is not equally long as the window. */
    00225     if (top > bottom || (top < bottom && panel_nwi->current_y > panel_nwi->smallest_y)) {
    00226       ResizeWindow(this, 0, top - bottom);
    00227     }
    00228   }
    00229
    00230   void SelectOtherAirport(byte airport_id)
    00231   {
    00232     this->RaiseWidget(_selected_airport_type + BAW_SMALL_AIRPORT);
    00233     _selected_airport_type = airport_id;
    00234     this->LowerWidget(airport_id + BAW_SMALL_AIRPORT);
    00235
    00236     const AirportSpec *as = AirportSpec::Get(airport_id);
    00237     SetTileSelectSize(as->size_x, as->size_y);
    00238
    00239     int rad = _settings_game.station.modified_catchment ? as->catchment : (uint)CA_UNMODIFIED;
    00240     if (_settings_client.gui.station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
    00241
    00242     this->SetDirty();
    00243   }
    00244
    00245   virtual void OnInvalidateData(int data = 0)
    00246   {
    00247     if (!AirportSpec::Get(_selected_airport_type)->IsAvailable()) {
    00248       for (int i = 0; i < BAW_AIRPORT_COUNT; i++) {
    00249         if (AirportSpec::Get(i)->IsAvailable()) {
    00250           this->SelectOtherAirport(i);
    00251           break;
    00252         }
    00253       }
    00254     }
    00255     for (int i = 0; i < BAW_AIRPORT_COUNT; i++) {
    00256       this->SetWidgetDisabledState(i + BAW_SMALL_AIRPORT, !AirportSpec::Get(i)->IsAvailable());
    00257     }
    00258   }
    00259
    00260   virtual void OnClick(Point pt, int widget)
    00261   {
    00262     switch (widget) {
    00263       case BAW_SMALL_AIRPORT: case BAW_CITY_AIRPORT: case BAW_HELIPORT: case BAW_METRO_AIRPORT:
    00264       case BAW_INTERNATIONAL_AIRPORT: case BAW_COMMUTER_AIRPORT: case BAW_HELIDEPOT:
    00265       case BAW_INTERCONTINENTAL_AIRPORT: case BAW_HELISTATION:
    00266         this->SelectOtherAirport(widget - BAW_SMALL_AIRPORT);
    00267         SndPlayFx(SND_15_BEEP);
    00268         DeleteWindowById(WC_SELECT_STATION, 0);
    00269         break;
    00270
    00271       case BAW_BTN_DONTHILIGHT: case BAW_BTN_DOHILIGHT:
    00272         _settings_client.gui.station_show_coverage = (widget != BAW_BTN_DONTHILIGHT);
    00273         this->SetWidgetLoweredState(BAW_BTN_DONTHILIGHT, !_settings_client.gui.station_show_coverage);
    00274         this->SetWidgetLoweredState(BAW_BTN_DOHILIGHT, _settings_client.gui.station_show_coverage);
    00275         SndPlayFx(SND_15_BEEP);
    00276         this->SelectOtherAirport(_selected_airport_type);
    00277         break;
    00278     }
    00279   }
    00280
    00281   virtual void OnTick()
    00282   {
    00283     CheckRedrawStationCoverage(this);
    00284   }
    00285 };
    00286
    00287 static const NWidgetPart _nested_build_airport_widgets[] = {
    00288   NWidget(NWID_HORIZONTAL),
    00289     NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
    00290     NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_AIRPORT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
    00291   EndContainer(),
    00292   /* Small airports. */
    00293   NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
    00294     NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(148, 14), SetFill(1, 0), SetDataTip(STR_STATION_BUILD_AIRPORT_SMALL_AIRPORTS, STR_NULL),
    00295     NWidget(NWID_HORIZONTAL),
    00296       NWidget(NWID_SPACER), SetMinimalSize(2, 0),
    00297       NWidget(NWID_VERTICAL),
    00298         NWidget(WWT_TEXTBTN, COLOUR_GREY, BAW_SMALL_AIRPORT), SetMinimalSize(144, 12), SetFill(1, 0),
    00299                   SetDataTip(STR_STATION_BUILD_AIRPORT_SMALL_AIRPORT, STR_STATION_BUILD_AIRPORT_TOOLTIP),
    00300         NWidget(WWT_TEXTBTN, COLOUR_GREY, BAW_COMMUTER_AIRPORT), SetMinimalSize(144, 12), SetFill(1, 0),
    00301                   SetDataTip(STR_STATION_BUILD_AIRPORT_COMMUTER_AIRPORT, STR_STATION_BUILD_AIRPORT_TOOLTIP),
    00302         NWidget(NWID_SPACER), SetMinimalSize(0, 1), SetFill(1, 0),
    00303       EndContainer(),
    00304       NWidget(NWID_SPACER), SetMinimalSize(2, 0),
    00305     EndContainer(),
    00306   EndContainer(),
    00307   /* Large airports. */
    00308   NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
    00309     NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(148, 14), SetFill(1, 0), SetDataTip(STR_STATION_BUILD_AIRPORT_LARGE_AIRPORTS, STR_NULL),
    00310     NWidget(NWID_HORIZONTAL),
    00311       NWidget(NWID_SPACER), SetMinimalSize(2, 0),
    00312       NWidget(NWID_VERTICAL),
    00313         NWidget(WWT_TEXTBTN, COLOUR_GREY, BAW_CITY_AIRPORT), SetMinimalSize(144, 12), SetFill(1, 0),
    00314                   SetDataTip(STR_STATION_BUILD_AIRPORT_CITY_AIRPORT, STR_STATION_BUILD_AIRPORT_TOOLTIP),
    00315         NWidget(WWT_TEXTBTN, COLOUR_GREY, BAW_METRO_AIRPORT), SetMinimalSize(144, 12), SetFill(1, 0),
    00316                   SetDataTip(STR_STATION_BUILD_AIRPORT_METRO_AIRPORT, STR_STATION_BUILD_AIRPORT_TOOLTIP),
    00317         NWidget(NWID_SPACER), SetMinimalSize(0, 1), SetFill(1, 0),
    00318       EndContainer(),
    00319       NWidget(NWID_SPACER), SetMinimalSize(2, 0),
    00320     EndContainer(),
    00321   EndContainer(),
    00322   /* Hub airports. */
    00323   NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
    00324     NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(148, 14), SetFill(1, 0), SetDataTip(STR_STATION_BUILD_AIRPORT_HUB_AIRPORTS, STR_NULL),
    00325     NWidget(NWID_HORIZONTAL),
    00326       NWidget(NWID_SPACER), SetMinimalSize(2, 0),
    00327       NWidget(NWID_VERTICAL),
    00328         NWidget(WWT_TEXTBTN, COLOUR_GREY, BAW_INTERNATIONAL_AIRPORT), SetMinimalSize(144, 12), SetFill(1, 0),
    00329                   SetDataTip(STR_STATION_BUILD_AIRPORT_INTERNATIONAL_AIRPORT, STR_STATION_BUILD_AIRPORT_TOOLTIP),
    00330         NWidget(WWT_TEXTBTN, COLOUR_GREY, BAW_INTERCONTINENTAL_AIRPORT), SetMinimalSize(144, 12), SetFill(1, 0),
    00331                   SetDataTip(STR_STATION_BUILD_AIRPORT_INTERCONTINENTAL_AIRPORT, STR_STATION_BUILD_AIRPORT_TOOLTIP),
    00332         NWidget(NWID_SPACER), SetMinimalSize(0, 1), SetFill(1, 0),
    00333       EndContainer(),
    00334       NWidget(NWID_SPACER), SetMinimalSize(2, 0),
    00335     EndContainer(),
    00336   EndContainer(),
    00337   /* Heliports. */
    00338   NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
    00339     NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(148, 14), SetFill(1, 0), SetDataTip(STR_STATION_BUILD_AIRPORT_HELIPORTS, STR_NULL),
    00340     NWidget(NWID_HORIZONTAL),
    00341       NWidget(NWID_SPACER), SetMinimalSize(2, 0),
    00342       NWidget(NWID_VERTICAL),
    00343         NWidget(WWT_TEXTBTN, COLOUR_GREY, BAW_HELIPORT), SetMinimalSize(144, 12), SetFill(1, 0),
    00344                   SetDataTip(STR_STATION_BUILD_AIRPORT_HELIPORT, STR_STATION_BUILD_AIRPORT_TOOLTIP),
    00345         NWidget(WWT_TEXTBTN, COLOUR_GREY, BAW_HELISTATION), SetMinimalSize(144, 12), SetFill(1, 0),
    00346                   SetDataTip(STR_STATION_BUILD_AIRPORT_HELISTATION, STR_STATION_BUILD_AIRPORT_TOOLTIP),
    00347         NWidget(WWT_TEXTBTN, COLOUR_GREY, BAW_HELIDEPOT), SetMinimalSize(144, 12), SetFill(1, 0),
    00348                   SetDataTip(STR_STATION_BUILD_AIRPORT_HELIDEPOT, STR_STATION_BUILD_AIRPORT_TOOLTIP),
    00349         NWidget(NWID_SPACER), SetMinimalSize(0, 1), SetFill(1, 0),
    00350       EndContainer(),
    00351       NWidget(NWID_SPACER), SetMinimalSize(2, 0),
    00352     EndContainer(),
    00353   EndContainer(),
    00354   /* Bottom panel. */
    00355   NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BAW_BOTTOMPANEL),
    00356     NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(148, 14), SetFill(1, 0), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL),
    00357     NWidget(NWID_HORIZONTAL),
    00358       NWidget(NWID_SPACER), SetMinimalSize(14, 0),
    00359       NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
    00360         NWidget(WWT_TEXTBTN, COLOUR_GREY, BAW_BTN_DONTHILIGHT), SetMinimalSize(60, 12), SetFill(1, 0),
    00361                       SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
    00362         NWidget(WWT_TEXTBTN, COLOUR_GREY, BAW_BTN_DOHILIGHT), SetMinimalSize(60, 12), SetFill(1, 0),
    00363                       SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
    00364       EndContainer(),
    00365       NWidget(NWID_SPACER), SetMinimalSize(14, 0),
    00366     EndContainer(),
    00367     NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetResize(0, 1), SetFill(1, 0),
    00368   EndContainer(),
    00369 };
    00370
    00371 static const WindowDesc _build_airport_desc(
    00372   WDP_AUTO, 0, 0,
    00373   WC_BUILD_STATION, WC_BUILD_TOOLBAR,
    00374   WDF_CONSTRUCTION,
    00375   _nested_build_airport_widgets, lengthof(_nested_build_airport_widgets)
    00376 );
    00377
    00378 static void ShowBuildAirportPicker(Window *parent)
    00379 {
    00380   new AirportPickerWindow(&_build_airport_desc, parent);
    00381 }
    00382
    00383 void InitializeAirportGui()
    00384 {
    00385   _selected_airport_type = AT_SMALL;
    00386 }