tron@2186: /* $Id$ */ tron@2186: rubidium@9111: /** @file airport_gui.cpp The GUI for airports. */ belugas@6117: truelight@0: #include "stdafx.h" Darkvater@1891: #include "openttd.h" rubidium@8107: #include "window_gui.h" truelight@0: #include "gui.h" rubidium@8107: #include "station_gui.h" rubidium@8205: #include "terraform_gui.h" rubidium@8116: #include "command_func.h" truelight@0: #include "airport.h" rubidium@8157: #include "sound_func.h" rubidium@8131: #include "window_func.h" rubidium@8270: #include "settings_type.h" rubidium@8224: #include "viewport_func.h" rubidium@8224: #include "gfx_func.h" rubidium@8254: #include "player_func.h" rubidium@8784: #include "order_func.h" rubidium@8962: #include "station_type.h" rubidium@9127: #include "tilehighlight_func.h" truelight@0: rubidium@8264: #include "table/sprites.h" rubidium@8264: #include "table/strings.h" rubidium@8264: truelight@0: static byte _selected_airport_type; truelight@0: rubidium@6247: static void ShowBuildAirportPicker(); 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@7521: 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: { rubidium@7889: if (HandlePlacePushButton(w, ATW_AIRPORT, SPR_CURSOR_AIRPORT, VHM_RECT, PlaceAirport)) ShowBuildAirportPicker(); truelight@0: } truelight@0: truelight@0: static void BuildAirClick_Demolish(Window *w) truelight@0: { belugas@9123: 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: truelight@0: static void BuildAirToolbWndProc(Window *w, WindowEvent *e) truelight@0: { tron@2639: switch (e->event) { belugas@8879: case WE_PAINT: belugas@8879: DrawWindowWidgets(w); belugas@8879: break; truelight@0: belugas@8879: case WE_CLICK: belugas@8879: if (e->we.click.widget - 3 >= 0) belugas@8879: _build_air_button_proc[e->we.click.widget - 3](w); belugas@8879: break; truelight@0: belugas@8879: case WE_KEYPRESS: { belugas@8879: switch (e->we.keypress.keycode) { belugas@8879: case '1': BuildAirClick_Airport(w); break; belugas@8879: case '2': BuildAirClick_Demolish(w); break; belugas@8879: default: return; belugas@8879: } belugas@8879: } break; belugas@4719: belugas@8879: case WE_PLACE_OBJ: belugas@8879: _place_proc(e->we.place.tile); belugas@8879: break; peter1138@2619: belugas@8879: case WE_PLACE_DRAG: belugas@8879: VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.select_method); belugas@8879: break; belugas@8879: belugas@8879: case WE_PLACE_MOUSEUP: belugas@8879: if (e->we.place.pt.x != -1 && e->we.place.select_proc == DDSP_DEMOLISH_AREA) { belugas@9163: GUIPlaceProcDragXY(e); belugas@8879: } belugas@8879: break; belugas@8879: belugas@8879: case WE_ABORT_PLACE_OBJ: belugas@8879: w->RaiseButtons(); belugas@8879: rubidium@9238: delete FindWindowById(WC_BUILD_STATION, 0); belugas@8879: break; belugas@8879: belugas@8879: case WE_DESTROY: belugas@8879: if (_patches.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0); belugas@8879: break; truelight@0: } truelight@0: } 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@5682: { WWT_CAPTION, RESIZE_NONE, 7, 11, 51, 0, 13, STR_A000_AIRPORTS, STR_018C_WINDOW_TITLE_DRAG_THIS }, tron@5682: { 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@7341: WDP_ALIGN_TBR, 22, 64, 36, 64, 36, rubidium@5893: 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: BuildAirToolbWndProc truelight@0: }; truelight@0: rubidium@6247: void ShowBuildAirToolbar() truelight@0: { Darkvater@5005: if (!IsValidPlayer(_current_player)) return; Darkvater@5005: rubidium@9080: DeleteWindowByClass(WC_BUILD_TOOLBAR); rubidium@9143: Window *w = AllocateWindowDescFront(&_air_toolbar_desc, TRANSPORT_AIR); tron@5860: if (_patches.link_terraform_toolbar) ShowTerraformToolbar(w); truelight@0: } truelight@0: belugas@9268: class AirportPickerWindow : public PickerWindowBase { belugas@8879: belugas@9268: enum { belugas@9268: BAW_BOTTOMPANEL = 10, belugas@9268: BAW_SMALL_AIRPORT, belugas@9268: BAW_CITY_AIRPORT, belugas@9268: BAW_HELIPORT, belugas@9268: BAW_METRO_AIRPORT, belugas@9268: BAW_STR_INTERNATIONAL_AIRPORT, belugas@9268: BAW_COMMUTER_AIRPORT, belugas@9268: BAW_HELIDEPOT, belugas@9268: BAW_STR_INTERCONTINENTAL_AIRPORT, belugas@9268: BAW_HELISTATION, belugas@9268: BAW_LAST_AIRPORT = BAW_HELISTATION, belugas@9268: BAW_AIRPORT_COUNT = BAW_LAST_AIRPORT - BAW_SMALL_AIRPORT + 1, belugas@9268: BAW_BTN_DONTHILIGHT = BAW_LAST_AIRPORT + 1, belugas@9268: BAW_BTN_DOHILIGHT, belugas@9268: }; truelight@0: belugas@9268: public: truelight@0: belugas@9268: AirportPickerWindow(const WindowDesc *desc) : PickerWindowBase(desc) belugas@9268: { belugas@9268: this->SetWidgetLoweredState(BAW_BTN_DONTHILIGHT, !_station_show_coverage); belugas@9268: this->SetWidgetLoweredState(BAW_BTN_DOHILIGHT, _station_show_coverage); belugas@9268: this->LowerWidget(_selected_airport_type + BAW_SMALL_AIRPORT); tron@1109: belugas@9268: this->FindWindowPlacementAndResize(desc); belugas@9268: } belugas@8879: belugas@9268: virtual void OnPaint() belugas@9268: { belugas@9268: int i; // airport enabling loop belugas@9268: uint32 avail_airports; belugas@9268: const AirportFTAClass *airport; belugas@9268: belugas@9268: avail_airports = GetValidAirports(); belugas@9268: belugas@9268: this->RaiseWidget(_selected_airport_type + BAW_SMALL_AIRPORT); belugas@9268: if (!HasBit(avail_airports, 0) && _selected_airport_type == AT_SMALL) _selected_airport_type = AT_LARGE; belugas@9268: if (!HasBit(avail_airports, 1) && _selected_airport_type == AT_LARGE) _selected_airport_type = AT_SMALL; belugas@9268: this->LowerWidget(_selected_airport_type + BAW_SMALL_AIRPORT); belugas@9268: belugas@9268: /* 'Country Airport' starts at widget BAW_SMALL_AIRPORT, and if its bit is set, it is belugas@9268: * available, so take its opposite value to set the disabled state. belugas@9268: * There are 9 buildable airports belugas@9268: * XXX TODO : all airports should be held in arrays, with all relevant data. belugas@9268: * This should be part of newgrf-airports, i suppose belugas@9268: */ belugas@9268: for (i = 0; i < BAW_AIRPORT_COUNT; i++) this->SetWidgetDisabledState(i + BAW_SMALL_AIRPORT, !HasBit(avail_airports, i)); belugas@9268: belugas@9268: /* select default the coverage area to 'Off' (16) */ belugas@9268: airport = GetAirport(_selected_airport_type); belugas@9268: SetTileSelectSize(airport->size_x, airport->size_y); belugas@9268: belugas@9268: int rad = _patches.modified_catchment ? airport->catchment : (uint)CA_UNMODIFIED; belugas@9268: belugas@9268: if (_station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad); belugas@9268: belugas@9268: DrawWindowWidgets(this); belugas@9268: /* strings such as 'Size' and 'Coverage Area' */ belugas@9268: int text_end = DrawStationCoverageAreaText(2, 206, SCT_ALL, rad, false); belugas@9268: text_end = DrawStationCoverageAreaText(2, text_end + 4, SCT_ALL, rad, true) + 4; belugas@9268: if (text_end != this->widget[BAW_BOTTOMPANEL].bottom) { belugas@9268: this->SetDirty(); belugas@9268: ResizeWindowForWidget(this, BAW_BOTTOMPANEL, 0, text_end - this->widget[BAW_BOTTOMPANEL].bottom); belugas@9268: this->SetDirty(); belugas@9268: } truelight@0: } belugas@9268: belugas@9268: virtual void OnClick(Point pt, int widget) belugas@9268: { belugas@9268: switch (widget) { belugas@9268: case BAW_SMALL_AIRPORT: case BAW_CITY_AIRPORT: case BAW_HELIPORT: case BAW_METRO_AIRPORT: belugas@9268: case BAW_STR_INTERNATIONAL_AIRPORT: case BAW_COMMUTER_AIRPORT: case BAW_HELIDEPOT: belugas@9268: case BAW_STR_INTERCONTINENTAL_AIRPORT: case BAW_HELISTATION: belugas@9268: this->RaiseWidget(_selected_airport_type + BAW_SMALL_AIRPORT); belugas@9268: _selected_airport_type = widget - BAW_SMALL_AIRPORT; belugas@9268: this->LowerWidget(_selected_airport_type + BAW_SMALL_AIRPORT); belugas@9268: SndPlayFx(SND_15_BEEP); belugas@9268: this->SetDirty(); belugas@9268: break; belugas@9268: belugas@9268: case BAW_BTN_DONTHILIGHT: case BAW_BTN_DOHILIGHT: belugas@9268: _station_show_coverage = (widget != BAW_BTN_DONTHILIGHT); belugas@9268: this->SetWidgetLoweredState(BAW_BTN_DONTHILIGHT, !_station_show_coverage); belugas@9268: this->SetWidgetLoweredState(BAW_BTN_DOHILIGHT, _station_show_coverage); belugas@9268: SndPlayFx(SND_15_BEEP); belugas@9268: this->SetDirty(); belugas@9268: break; belugas@9268: } belugas@9268: } belugas@9268: belugas@9268: virtual void OnTick() belugas@9268: { belugas@9268: CheckRedrawStationCoverage(this); belugas@9268: } belugas@9268: }; 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@8910: { 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@8910: { 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@8910: { 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@8910: { WWT_LABEL, RESIZE_NONE, 7, 0, 147, 128, 141, STR_HELIPORTS, STR_NULL}, belugas@8910: { 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@7341: 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, belugas@9268: NULL truelight@0: }; truelight@0: rubidium@6247: static void ShowBuildAirportPicker() truelight@0: { belugas@9268: new AirportPickerWindow(&_build_airport_desc); truelight@0: } truelight@0: rubidium@6247: void InitializeAirportGui() truelight@0: { truelight@0: _selected_airport_type = AT_SMALL; truelight@0: }