tron@2186: /* $Id$ */ tron@2186: rubidium@10429: /** @file airport_gui.cpp The GUI for airports. */ belugas@6443: truelight@0: #include "stdafx.h" Darkvater@1891: #include "openttd.h" rubidium@8603: #include "window_gui.h" truelight@0: #include "gui.h" rubidium@8603: #include "station_gui.h" rubidium@8701: #include "terraform_gui.h" rubidium@8612: #include "command_func.h" truelight@0: #include "airport.h" rubidium@8653: #include "sound_func.h" rubidium@8627: #include "window_func.h" belugas@10682: #include "strings_func.h" rubidium@8766: #include "settings_type.h" rubidium@8720: #include "viewport_func.h" rubidium@8720: #include "gfx_func.h" rubidium@8750: #include "player_func.h" rubidium@9280: #include "order_func.h" rubidium@10222: #include "station_type.h" rubidium@10445: #include "tilehighlight_func.h" truelight@0: rubidium@8760: #include "table/sprites.h" rubidium@8760: #include "table/strings.h" rubidium@8760: truelight@0: static byte _selected_airport_type; truelight@0: frosch@10686: static void ShowBuildAirportPicker(Window *parent); truelight@0: truelight@0: tron@1977: void CcBuildAirport(bool success, TileIndex tile, uint32 p1, uint32 p2) truelight@0: { truelight@0: if (success) { tron@541: SndPlayTileFx(SND_1F_SPLAT, tile); truelight@0: ResetObjectToPlace(); truelight@0: } truelight@0: } truelight@0: tron@1977: static void PlaceAirport(TileIndex tile) truelight@0: { rubidium@8017: DoCommandP(tile, _selected_airport_type, _ctrl_pressed, CcBuildAirport, CMD_BUILD_AIRPORT | CMD_NO_WATER | CMD_MSG(STR_A001_CAN_T_BUILD_AIRPORT_HERE)); truelight@0: } truelight@0: truelight@0: tron@5147: enum { tron@5147: ATW_AIRPORT = 3, tron@5147: ATW_DEMOLISH = 4 tron@5147: }; tron@5147: tron@5147: truelight@0: static void BuildAirClick_Airport(Window *w) truelight@0: { frosch@10686: if (HandlePlacePushButton(w, ATW_AIRPORT, SPR_CURSOR_AIRPORT, VHM_RECT, PlaceAirport)) ShowBuildAirportPicker(w); truelight@0: } truelight@0: truelight@0: static void BuildAirClick_Demolish(Window *w) truelight@0: { belugas@10441: HandlePlacePushButton(w, ATW_DEMOLISH, ANIMCURSOR_DEMOLISH, VHM_RECT, PlaceProc_DemolishArea); truelight@0: } truelight@0: truelight@0: truelight@0: typedef void OnButtonClick(Window *w); truelight@0: static OnButtonClick * const _build_air_button_proc[] = { truelight@0: BuildAirClick_Airport, truelight@0: BuildAirClick_Demolish, truelight@0: }; truelight@0: rubidium@10627: struct BuildAirToolbarWindow : Window { rubidium@10627: BuildAirToolbarWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number) rubidium@10627: { rubidium@10627: this->FindWindowPlacementAndResize(desc); rubidium@10775: if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this); rubidium@10627: } belugas@4719: rubidium@10627: ~BuildAirToolbarWindow() rubidium@10627: { rubidium@10775: if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0); rubidium@10627: } belugas@10115: rubidium@10627: virtual void OnPaint() rubidium@10627: { rubidium@10627: this->DrawWidgets(); rubidium@10627: } belugas@10115: rubidium@10627: virtual void OnClick(Point pt, int widget) rubidium@10627: { rubidium@10627: if (widget - 3 >= 0) { rubidium@10627: _build_air_button_proc[widget - 3](this); rubidium@10627: } rubidium@10627: } belugas@10115: belugas@10115: rubidium@10627: virtual EventState OnKeyPress(uint16 key, uint16 keycode) rubidium@10627: { rubidium@10627: switch (keycode) { rubidium@10627: case '1': BuildAirClick_Airport(this); break; rubidium@10627: case '2': BuildAirClick_Demolish(this); break; rubidium@10627: default: return ES_NOT_HANDLED; rubidium@10627: } rubidium@10627: return ES_HANDLED; truelight@0: } rubidium@10627: rubidium@10627: virtual void OnPlaceObject(Point pt, TileIndex tile) rubidium@10627: { rubidium@10627: _place_proc(tile); rubidium@10627: } rubidium@10627: rubidium@10627: virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) rubidium@10627: { rubidium@10627: VpSelectTilesWithMethod(pt.x, pt.y, select_method); rubidium@10627: } rubidium@10627: rubidium@10627: virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) rubidium@10627: { rubidium@10627: if (pt.x != -1 && select_proc == DDSP_DEMOLISH_AREA) { rubidium@10627: GUIPlaceProcDragXY(select_proc, start_tile, end_tile); rubidium@10627: } rubidium@10627: } rubidium@10627: rubidium@10627: virtual void OnPlaceObjectAbort() rubidium@10627: { rubidium@10627: this->RaiseButtons(); rubidium@10627: rubidium@10627: delete FindWindowById(WC_BUILD_STATION, 0); rubidium@10627: } rubidium@10627: }; truelight@0: truelight@0: static const Widget _air_toolbar_widgets[] = { rubidium@4344: { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW }, tron@5933: { WWT_CAPTION, RESIZE_NONE, 7, 11, 51, 0, 13, STR_A000_AIRPORTS, STR_018C_WINDOW_TITLE_DRAG_THIS }, tron@5933: { WWT_STICKYBOX, RESIZE_NONE, 7, 52, 63, 0, 13, 0x0, STR_STICKY_BUTTON }, Darkvater@4937: { WWT_IMGBTN, RESIZE_NONE, 7, 0, 41, 14, 35, SPR_IMG_AIRPORT, STR_A01E_BUILD_AIRPORT }, Darkvater@4937: { WWT_IMGBTN, RESIZE_NONE, 7, 42, 63, 14, 35, SPR_IMG_DYNAMITE, STR_018D_DEMOLISH_BUILDINGS_ETC }, darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: truelight@0: static const WindowDesc _air_toolbar_desc = { rubidium@7837: WDP_ALIGN_TBR, 22, 64, 36, 64, 36, rubidium@6144: WC_BUILD_TOOLBAR, WC_NONE, darkvater@756: WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON, truelight@0: _air_toolbar_widgets, truelight@0: }; truelight@0: rubidium@6573: void ShowBuildAirToolbar() truelight@0: { rubidium@11161: if (!IsValidPlayerID(_current_player)) return; Darkvater@5005: rubidium@10397: DeleteWindowByClass(WC_BUILD_TOOLBAR); rubidium@10627: AllocateWindowDescFront(&_air_toolbar_desc, TRANSPORT_AIR); truelight@0: } truelight@0: belugas@10590: class AirportPickerWindow : public PickerWindowBase { belugas@10115: belugas@10590: enum { belugas@10590: BAW_BOTTOMPANEL = 10, belugas@10590: BAW_SMALL_AIRPORT, belugas@10590: BAW_CITY_AIRPORT, belugas@10590: BAW_HELIPORT, belugas@10590: BAW_METRO_AIRPORT, belugas@10590: BAW_STR_INTERNATIONAL_AIRPORT, belugas@10590: BAW_COMMUTER_AIRPORT, belugas@10590: BAW_HELIDEPOT, belugas@10590: BAW_STR_INTERCONTINENTAL_AIRPORT, belugas@10590: BAW_HELISTATION, belugas@10590: BAW_LAST_AIRPORT = BAW_HELISTATION, belugas@10590: BAW_AIRPORT_COUNT = BAW_LAST_AIRPORT - BAW_SMALL_AIRPORT + 1, belugas@10590: BAW_BTN_DONTHILIGHT = BAW_LAST_AIRPORT + 1, belugas@10590: BAW_BTN_DOHILIGHT, belugas@10590: }; truelight@0: belugas@10590: public: truelight@0: frosch@10686: AirportPickerWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(desc, parent) belugas@10590: { belugas@10590: this->SetWidgetLoweredState(BAW_BTN_DONTHILIGHT, !_station_show_coverage); belugas@10590: this->SetWidgetLoweredState(BAW_BTN_DOHILIGHT, _station_show_coverage); belugas@10590: this->LowerWidget(_selected_airport_type + BAW_SMALL_AIRPORT); tron@1109: rubidium@10775: if (_settings_game.economy.station_noise_level) { belugas@10682: ResizeWindowForWidget(this, BAW_BOTTOMPANEL, 0, 10); belugas@10682: } belugas@10682: belugas@10590: this->FindWindowPlacementAndResize(desc); belugas@10590: } belugas@10115: belugas@10590: virtual void OnPaint() belugas@10590: { belugas@10590: int i; // airport enabling loop belugas@10682: uint16 y_noise_offset = 0; belugas@10590: uint32 avail_airports; belugas@10590: const AirportFTAClass *airport; belugas@10590: belugas@10590: avail_airports = GetValidAirports(); belugas@10590: belugas@10590: this->RaiseWidget(_selected_airport_type + BAW_SMALL_AIRPORT); belugas@10590: if (!HasBit(avail_airports, 0) && _selected_airport_type == AT_SMALL) _selected_airport_type = AT_LARGE; belugas@10590: if (!HasBit(avail_airports, 1) && _selected_airport_type == AT_LARGE) _selected_airport_type = AT_SMALL; belugas@10590: this->LowerWidget(_selected_airport_type + BAW_SMALL_AIRPORT); belugas@10590: belugas@10590: /* 'Country Airport' starts at widget BAW_SMALL_AIRPORT, and if its bit is set, it is belugas@10590: * available, so take its opposite value to set the disabled state. belugas@10590: * There are 9 buildable airports belugas@10590: * XXX TODO : all airports should be held in arrays, with all relevant data. belugas@10590: * This should be part of newgrf-airports, i suppose belugas@10590: */ belugas@10590: for (i = 0; i < BAW_AIRPORT_COUNT; i++) this->SetWidgetDisabledState(i + BAW_SMALL_AIRPORT, !HasBit(avail_airports, i)); belugas@10590: belugas@10590: /* select default the coverage area to 'Off' (16) */ belugas@10590: airport = GetAirport(_selected_airport_type); belugas@10590: SetTileSelectSize(airport->size_x, airport->size_y); belugas@10590: rubidium@10775: int rad = _settings_game.station.modified_catchment ? airport->catchment : (uint)CA_UNMODIFIED; belugas@10590: belugas@10590: if (_station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad); belugas@10590: rubidium@10595: this->DrawWidgets(); belugas@10682: belugas@10682: /* only show the station (airport) noise, if the noise option is activated */ rubidium@10775: if (_settings_game.economy.station_noise_level) { belugas@10682: /* show the noise of the selected airport */ belugas@10682: SetDParam(0, airport->noise_level); belugas@10682: DrawString(2, 206, STR_STATION_NOISE, 0); belugas@10682: y_noise_offset = 10; belugas@10682: } belugas@10682: belugas@10590: /* strings such as 'Size' and 'Coverage Area' */ belugas@10682: int text_end = DrawStationCoverageAreaText(2, this->widget[BAW_BTN_DOHILIGHT].bottom + 4 + y_noise_offset, SCT_ALL, rad, false); belugas@10590: text_end = DrawStationCoverageAreaText(2, text_end + 4, SCT_ALL, rad, true) + 4; belugas@10590: if (text_end != this->widget[BAW_BOTTOMPANEL].bottom) { belugas@10590: this->SetDirty(); belugas@10590: ResizeWindowForWidget(this, BAW_BOTTOMPANEL, 0, text_end - this->widget[BAW_BOTTOMPANEL].bottom); belugas@10590: this->SetDirty(); belugas@10590: } truelight@0: } belugas@10590: belugas@10590: virtual void OnClick(Point pt, int widget) belugas@10590: { belugas@10590: switch (widget) { belugas@10590: case BAW_SMALL_AIRPORT: case BAW_CITY_AIRPORT: case BAW_HELIPORT: case BAW_METRO_AIRPORT: belugas@10590: case BAW_STR_INTERNATIONAL_AIRPORT: case BAW_COMMUTER_AIRPORT: case BAW_HELIDEPOT: belugas@10590: case BAW_STR_INTERCONTINENTAL_AIRPORT: case BAW_HELISTATION: belugas@10590: this->RaiseWidget(_selected_airport_type + BAW_SMALL_AIRPORT); belugas@10590: _selected_airport_type = widget - BAW_SMALL_AIRPORT; belugas@10590: this->LowerWidget(_selected_airport_type + BAW_SMALL_AIRPORT); belugas@10590: SndPlayFx(SND_15_BEEP); belugas@10590: this->SetDirty(); belugas@10590: break; belugas@10590: belugas@10590: case BAW_BTN_DONTHILIGHT: case BAW_BTN_DOHILIGHT: belugas@10590: _station_show_coverage = (widget != BAW_BTN_DONTHILIGHT); belugas@10590: this->SetWidgetLoweredState(BAW_BTN_DONTHILIGHT, !_station_show_coverage); belugas@10590: this->SetWidgetLoweredState(BAW_BTN_DOHILIGHT, _station_show_coverage); belugas@10590: SndPlayFx(SND_15_BEEP); belugas@10590: this->SetDirty(); belugas@10590: break; belugas@10590: } belugas@10590: } belugas@10590: belugas@10590: virtual void OnTick() belugas@10590: { belugas@10590: CheckRedrawStationCoverage(this); belugas@10590: } belugas@10590: }; truelight@0: truelight@0: static const Widget _build_airport_picker_widgets[] = { belugas@4345: { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, belugas@4345: { WWT_CAPTION, RESIZE_NONE, 7, 11, 147, 0, 13, STR_3001_AIRPORT_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS}, belugas@4345: { WWT_PANEL, RESIZE_NONE, 7, 0, 147, 14, 52, 0x0, STR_NULL}, belugas@10148: { WWT_LABEL, RESIZE_NONE, 7, 0, 147, 14, 27, STR_SMALL_AIRPORTS, STR_NULL}, belugas@4345: { WWT_PANEL, RESIZE_NONE, 7, 0, 147, 53, 89, 0x0, STR_NULL}, belugas@10148: { WWT_LABEL, RESIZE_NONE, 7, 0, 147, 52, 65, STR_LARGE_AIRPORTS, STR_NULL}, belugas@4345: { WWT_PANEL, RESIZE_NONE, 7, 0, 147, 90, 127, 0x0, STR_NULL}, belugas@10148: { WWT_LABEL, RESIZE_NONE, 7, 0, 147, 90, 103, STR_HUB_AIRPORTS, STR_NULL}, belugas@4345: { WWT_PANEL, RESIZE_NONE, 7, 0, 147, 128, 177, 0x0, STR_NULL}, belugas@10148: { WWT_LABEL, RESIZE_NONE, 7, 0, 147, 128, 141, STR_HELIPORTS, STR_NULL}, belugas@10148: { WWT_PANEL, RESIZE_NONE, 7, 0, 147, 178, 239, 0x0, STR_NULL}, // bottom general box glx@4968: { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 27, 38, STR_SMALL_AIRPORT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT}, glx@4968: { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 65, 76, STR_CITY_AIRPORT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT}, glx@4968: { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 141, 152, STR_HELIPORT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT}, glx@4968: { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 77, 88, STR_METRO_AIRPORT , STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT}, glx@4968: { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 103, 114, STR_INTERNATIONAL_AIRPORT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT}, glx@4968: { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 39, 50, STR_COMMUTER_AIRPORT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT}, glx@4968: { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 165, 176, STR_HELIDEPOT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT}, glx@4968: { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 115, 126, STR_INTERCONTINENTAL_AIRPORT, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT}, glx@4968: { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 145, 153, 164, STR_HELISTATION, STR_3058_SELECT_SIZE_TYPE_OF_AIRPORT}, belugas@4345: { WWT_TEXTBTN, RESIZE_NONE, 14, 14, 73, 191, 202, STR_02DB_OFF, STR_3065_DON_T_HIGHLIGHT_COVERAGE}, belugas@4345: { WWT_TEXTBTN, RESIZE_NONE, 14, 74, 133, 191, 202, STR_02DA_ON, STR_3064_HIGHLIGHT_COVERAGE_AREA}, belugas@4345: { WWT_LABEL, RESIZE_NONE, 7, 0, 147, 178, 191, STR_3066_COVERAGE_AREA_HIGHLIGHT, STR_NULL}, darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: static const WindowDesc _build_airport_desc = { rubidium@7837: WDP_AUTO, WDP_AUTO, 148, 240, 148, 240, Darkvater@5070: WC_BUILD_STATION, WC_BUILD_TOOLBAR, truelight@0: WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, truelight@0: _build_airport_picker_widgets, truelight@0: }; truelight@0: frosch@10686: static void ShowBuildAirportPicker(Window *parent) truelight@0: { frosch@10686: new AirportPickerWindow(&_build_airport_desc, parent); truelight@0: } truelight@0: rubidium@6573: void InitializeAirportGui() truelight@0: { truelight@0: _selected_airport_type = AT_SMALL; truelight@0: }