00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "openttd.h"
00014 #include "gui.h"
00015 #include "window_gui.h"
00016 #include "window_func.h"
00017 #include "viewport_func.h"
00018 #include "command_func.h"
00019 #include "variables.h"
00020 #include "vehicle_gui.h"
00021 #include "rail_gui.h"
00022 #include "road_gui.h"
00023 #include "date_func.h"
00024 #include "vehicle_func.h"
00025 #include "sound_func.h"
00026 #include "terraform_gui.h"
00027 #include "transparency.h"
00028 #include "strings_func.h"
00029 #include "company_func.h"
00030 #include "company_gui.h"
00031 #include "vehicle_base.h"
00032 #include "cheat_func.h"
00033 #include "transparency_gui.h"
00034 #include "screenshot.h"
00035 #include "signs_func.h"
00036 #include "fios.h"
00037 #include "functions.h"
00038 #include "console_gui.h"
00039 #include "news_gui.h"
00040 #include "ai/ai_gui.hpp"
00041 #include "tilehighlight_func.h"
00042 #include "rail.h"
00043 #include "widgets/dropdown_type.h"
00044
00045 #include "network/network.h"
00046 #include "network/network_gui.h"
00047 #include "network/network_func.h"
00048
00049 #include "table/strings.h"
00050 #include "table/sprites.h"
00051
00052 RailType _last_built_railtype;
00053 static RoadType _last_built_roadtype;
00054
00055 enum ToolbarMode {
00056 TB_NORMAL,
00057 TB_UPPER,
00058 TB_LOWER
00059 };
00060
00061 enum ToolbarNormalWidgets {
00062 TBN_PAUSE = 0,
00063 TBN_FASTFORWARD,
00064 TBN_SETTINGS,
00065 TBN_SAVEGAME,
00066 TBN_SMALLMAP,
00067 TBN_TOWNDIRECTORY,
00068 TBN_SUBSIDIES,
00069 TBN_STATIONS,
00070 TBN_FINANCES,
00071 TBN_COMPANIES,
00072 TBN_GRAPHICS,
00073 TBN_LEAGUE,
00074 TBN_INDUSTRIES,
00075 TBN_VEHICLESTART,
00076 TBN_TRAINS = TBN_VEHICLESTART,
00077 TBN_ROADVEHS,
00078 TBN_SHIPS,
00079 TBN_AIRCRAFTS,
00080 TBN_ZOOMIN,
00081 TBN_ZOOMOUT,
00082 TBN_RAILS,
00083 TBN_ROADS,
00084 TBN_WATER,
00085 TBN_AIR,
00086 TBN_LANDSCAPE,
00087 TBN_MUSICSOUND,
00088 TBN_NEWSREPORT,
00089 TBN_HELP,
00090 TBN_SWITCHBAR,
00091 TBN_END
00092 };
00093
00094 enum ToolbarScenEditorWidgets {
00095 TBSE_PAUSE = 0,
00096 TBSE_FASTFORWARD,
00097 TBSE_SETTINGS,
00098 TBSE_SAVESCENARIO,
00099 TBSE_SPACERPANEL,
00100 TBSE_DATEPANEL,
00101 TBSE_DATEBACKWARD,
00102 TBSE_DATEFORWARD,
00103 TBSE_SMALLMAP,
00104 TBSE_ZOOMIN,
00105 TBSE_ZOOMOUT,
00106 TBSE_LANDGENERATE,
00107 TBSE_TOWNGENERATE,
00108 TBSE_INDUSTRYGENERATE,
00109 TBSE_BUILDROAD,
00110 TBSE_BUILDDOCKS,
00111 TBSE_PLANTTREES,
00112 TBSE_PLACESIGNS,
00113 TBSE_DATEPANEL_CONTAINER,
00114 };
00115
00119 class DropDownListCheckedItem : public DropDownListStringItem {
00120 uint checkmark_width;
00121 public:
00122 bool checked;
00123
00124 DropDownListCheckedItem(StringID string, int result, bool masked, bool checked) : DropDownListStringItem(string, result, masked), checked(checked)
00125 {
00126 this->checkmark_width = GetStringBoundingBox(STR_JUST_CHECKMARK).width + 3;
00127 }
00128
00129 virtual ~DropDownListCheckedItem() {}
00130
00131 uint Width() const
00132 {
00133 return DropDownListStringItem::Width() + this->checkmark_width;
00134 }
00135
00136 void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
00137 {
00138 bool rtl = _dynlang.text_dir == TD_RTL;
00139 if (this->checked) {
00140 DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, STR_JUST_CHECKMARK, sel ? TC_WHITE : TC_BLACK);
00141 }
00142 DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : this->checkmark_width), right - WD_FRAMERECT_RIGHT - (rtl ? this->checkmark_width : 0), top, this->String(), sel ? TC_WHITE : TC_BLACK);
00143 }
00144 };
00145
00149 class DropDownListCompanyItem : public DropDownListItem {
00150 uint icon_width;
00151 public:
00152 bool greyed;
00153
00154 DropDownListCompanyItem(int result, bool masked, bool greyed) : DropDownListItem(result, masked), greyed(greyed)
00155 {
00156 this->icon_width = GetSpriteSize(SPR_COMPANY_ICON).width;
00157 }
00158
00159 virtual ~DropDownListCompanyItem() {}
00160
00161 bool Selectable() const
00162 {
00163 return true;
00164 }
00165
00166 uint Width() const
00167 {
00168 CompanyID company = (CompanyID)this->result;
00169 SetDParam(0, company);
00170 SetDParam(1, company);
00171 return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_width + 3;
00172 }
00173
00174 void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
00175 {
00176 CompanyID company = (CompanyID)this->result;
00177 bool rtl = _dynlang.text_dir == TD_RTL;
00178
00179
00180 if (!Company::IsValidID(company)) return;
00181
00182 DrawCompanyIcon(company, rtl ? right - this->icon_width - WD_FRAMERECT_RIGHT : left + WD_FRAMERECT_LEFT, top + 1 + (FONT_HEIGHT_NORMAL - 10) / 2);
00183
00184 SetDParam(0, company);
00185 SetDParam(1, company);
00186 TextColour col;
00187 if (this->greyed) {
00188 col = TC_GREY;
00189 } else {
00190 col = sel ? TC_WHITE : TC_BLACK;
00191 }
00192 DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : 3 + this->icon_width), right - WD_FRAMERECT_RIGHT - (rtl ? 3 + this->icon_width : 0), top, STR_COMPANY_NAME_COMPANY_NUM, col);
00193 }
00194 };
00195
00199 static void PopupMainToolbMenu(Window *w, int widget, StringID string, int count)
00200 {
00201 DropDownList *list = new DropDownList();
00202 for (int i = 0; i < count; i++) {
00203 list->push_back(new DropDownListStringItem(string + i, i, false));
00204 }
00205 ShowDropDownList(w, list, 0, widget, 140, true, true);
00206 SndPlayFx(SND_15_BEEP);
00207 }
00208
00210 enum {
00211 CTMN_CLIENT_LIST = -1,
00212 CTMN_NEW_COMPANY = -2,
00213 CTMN_SPECTATE = -3,
00214 };
00215
00219 static void PopupMainCompanyToolbMenu(Window *w, int widget, int grey = 0)
00220 {
00221 DropDownList *list = new DropDownList();
00222
00223 #ifdef ENABLE_NETWORK
00224 if (widget == TBN_COMPANIES && _networking) {
00225
00226 list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, CTMN_CLIENT_LIST, false));
00227
00228 if (_local_company == COMPANY_SPECTATOR) {
00229 list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_NEW_COMPANY, CTMN_NEW_COMPANY, NetworkMaxCompaniesReached()));
00230 } else {
00231 list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_SPECTATE, CTMN_SPECTATE, NetworkMaxSpectatorsReached()));
00232 }
00233 }
00234 #endif
00235
00236 for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
00237 if (!Company::IsValidID(c)) continue;
00238 list->push_back(new DropDownListCompanyItem(c, false, HasBit(grey, c)));
00239 }
00240
00241 ShowDropDownList(w, list, _local_company == COMPANY_SPECTATOR ? CTMN_CLIENT_LIST : (int)_local_company, widget, 240, true, true);
00242 SndPlayFx(SND_15_BEEP);
00243 }
00244
00245
00246 static ToolbarMode _toolbar_mode;
00247
00248 static void SelectSignTool()
00249 {
00250 if (_cursor.sprite == SPR_CURSOR_SIGN) {
00251 ResetObjectToPlace();
00252 } else {
00253 SetObjectToPlace(SPR_CURSOR_SIGN, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0);
00254 _place_proc = PlaceProc_Sign;
00255 }
00256 }
00257
00258
00259
00260 static void ToolbarPauseClick(Window *w)
00261 {
00262 if (_networking && !_network_server) return;
00263
00264 if (DoCommandP(0, PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED, CMD_PAUSE)) SndPlayFx(SND_15_BEEP);
00265 }
00266
00267
00268
00269 static void ToolbarFastForwardClick(Window *w)
00270 {
00271 _fast_forward ^= true;
00272 SndPlayFx(SND_15_BEEP);
00273 }
00274
00275
00276
00277 enum OptionMenuEntries {
00278 OME_GAMEOPTIONS,
00279 OME_DIFFICULTIES,
00280 OME_SETTINGS,
00281 OME_NEWGRFSETTINGS,
00282 OME_TRANSPARENCIES,
00283 OME_SHOW_TOWNNAMES,
00284 OME_SHOW_STATIONNAMES,
00285 OME_SHOW_WAYPOINTNAMES,
00286 OME_SHOW_SIGNS,
00287 OME_FULL_ANIMATION,
00288 OME_FULL_DETAILS,
00289 OME_TRANSPARENTBUILDINGS,
00290 OME_SHOW_STATIONSIGNS,
00291 };
00292
00293 static void ToolbarOptionsClick(Window *w)
00294 {
00295 DropDownList *list = new DropDownList();
00296 list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_GAME_OPTIONS, OME_GAMEOPTIONS, false));
00297 list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_DIFFICULTY_SETTINGS, OME_DIFFICULTIES, false));
00298 list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_CONFIG_SETTINGS, OME_SETTINGS, false));
00299 list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS, false));
00300 list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES, false));
00301 list->push_back(new DropDownListItem(-1, false));
00302 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES)));
00303 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false, HasBit(_display_opt, DO_SHOW_STATION_NAMES)));
00304 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED, OME_SHOW_WAYPOINTNAMES, false, HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES)));
00305 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_SIGNS_DISPLAYED, OME_SHOW_SIGNS, false, HasBit(_display_opt, DO_SHOW_SIGNS)));
00306 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_ANIMATION, OME_FULL_ANIMATION, false, HasBit(_display_opt, DO_FULL_ANIMATION)));
00307 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_DETAIL, OME_FULL_DETAILS, false, HasBit(_display_opt, DO_FULL_DETAIL)));
00308 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES)));
00309 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS)));
00310
00311 ShowDropDownList(w, list, 0, TBN_SETTINGS, 140, true, true);
00312 SndPlayFx(SND_15_BEEP);
00313 }
00314
00315 static void MenuClickSettings(int index)
00316 {
00317 switch (index) {
00318 case OME_GAMEOPTIONS: ShowGameOptions(); return;
00319 case OME_DIFFICULTIES: ShowGameDifficulty(); return;
00320 case OME_SETTINGS: ShowGameSettings(); return;
00321 case OME_NEWGRFSETTINGS: ShowNewGRFSettings(!_networking, true, true, &_grfconfig); return;
00322 case OME_TRANSPARENCIES: ShowTransparencyToolbar(); break;
00323
00324 case OME_SHOW_TOWNNAMES: ToggleBit(_display_opt, DO_SHOW_TOWN_NAMES); break;
00325 case OME_SHOW_STATIONNAMES: ToggleBit(_display_opt, DO_SHOW_STATION_NAMES); break;
00326 case OME_SHOW_WAYPOINTNAMES: ToggleBit(_display_opt, DO_SHOW_WAYPOINT_NAMES); break;
00327 case OME_SHOW_SIGNS: ToggleBit(_display_opt, DO_SHOW_SIGNS); break;
00328 case OME_FULL_ANIMATION: ToggleBit(_display_opt, DO_FULL_ANIMATION); break;
00329 case OME_FULL_DETAILS: ToggleBit(_display_opt, DO_FULL_DETAIL); break;
00330 case OME_TRANSPARENTBUILDINGS: ToggleTransparency(TO_HOUSES); break;
00331 case OME_SHOW_STATIONSIGNS: ToggleTransparency(TO_SIGNS); break;
00332 }
00333 MarkWholeScreenDirty();
00334 }
00335
00336
00337
00338 enum SaveLoadEditorMenuEntries {
00339 SLEME_SAVE_SCENARIO = 0,
00340 SLEME_LOAD_SCENARIO,
00341 SLEME_LOAD_HEIGHTMAP,
00342 SLEME_EXIT_TOINTRO,
00343 SLEME_EXIT_GAME = 5,
00344 SLEME_MENUCOUNT,
00345 };
00346
00347 enum SaveLoadNormalMenuEntries {
00348 SLNME_SAVE_GAME = 0,
00349 SLNME_LOAD_GAME,
00350 SLNME_EXIT_TOINTRO,
00351 SLNME_EXIT_GAME,
00352 SLNME_MENUCOUNT,
00353 };
00354
00355 static void ToolbarSaveClick(Window *w)
00356 {
00357 PopupMainToolbMenu(w, TBN_SAVEGAME, STR_FILE_MENU_SAVE_GAME, SLNME_MENUCOUNT);
00358 }
00359
00360 static void ToolbarScenSaveOrLoad(Window *w)
00361 {
00362 PopupMainToolbMenu(w, TBSE_SAVESCENARIO, STR_SCENEDIT_FILE_MENU_SAVE_SCENARIO, SLEME_MENUCOUNT);
00363 }
00364
00365 static void MenuClickSaveLoad(int index = 0)
00366 {
00367 if (_game_mode == GM_EDITOR) {
00368 switch (index) {
00369 case SLEME_SAVE_SCENARIO: ShowSaveLoadDialog(SLD_SAVE_SCENARIO); break;
00370 case SLEME_LOAD_SCENARIO: ShowSaveLoadDialog(SLD_LOAD_SCENARIO); break;
00371 case SLEME_LOAD_HEIGHTMAP: ShowSaveLoadDialog(SLD_LOAD_HEIGHTMAP); break;
00372 case SLEME_EXIT_TOINTRO: AskExitToGameMenu(); break;
00373 case SLEME_EXIT_GAME: HandleExitGameRequest(); break;
00374 }
00375 } else {
00376 switch (index) {
00377 case SLNME_SAVE_GAME: ShowSaveLoadDialog(SLD_SAVE_GAME); break;
00378 case SLNME_LOAD_GAME: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
00379 case SLNME_EXIT_TOINTRO: AskExitToGameMenu(); break;
00380 case SLNME_EXIT_GAME: HandleExitGameRequest(); break;
00381 }
00382 }
00383 }
00384
00385
00386
00387 enum MapMenuEntries {
00388 MME_SHOW_SMALLMAP = 0,
00389 MME_SHOW_EXTRAVIEWPORTS,
00390 MME_SHOW_SIGNLISTS,
00391 MME_SHOW_TOWNDIRECTORY,
00392 MME_MENUCOUNT_NORMAL = 3,
00393 MME_MENUCOUNT_EDITOR = 4,
00394 };
00395
00396 static void ToolbarMapClick(Window *w)
00397 {
00398 PopupMainToolbMenu(w, TBN_SMALLMAP, STR_MAP_MENU_MAP_OF_WORLD, MME_MENUCOUNT_NORMAL);
00399 }
00400
00401 static void ToolbarScenMapTownDir(Window *w)
00402 {
00403 PopupMainToolbMenu(w, TBSE_SMALLMAP, STR_MAP_MENU_MAP_OF_WORLD, MME_MENUCOUNT_EDITOR);
00404 }
00405
00406 static void MenuClickMap(int index)
00407 {
00408 switch (index) {
00409 case MME_SHOW_SMALLMAP: ShowSmallMap(); break;
00410 case MME_SHOW_EXTRAVIEWPORTS: ShowExtraViewPortWindow(); break;
00411 case MME_SHOW_SIGNLISTS: ShowSignList(); break;
00412 case MME_SHOW_TOWNDIRECTORY: if (_game_mode == GM_EDITOR) ShowTownDirectory(); break;
00413 }
00414 }
00415
00416
00417
00418 static void ToolbarTownClick(Window *w)
00419 {
00420 PopupMainToolbMenu(w, TBN_TOWNDIRECTORY, STR_TOWN_MENU_TOWN_DIRECTORY, (_settings_game.economy.found_town == TF_FORBIDDEN) ? 1 : 2);
00421 }
00422
00423 static void MenuClickTown(int index)
00424 {
00425 switch (index) {
00426 case 0: ShowTownDirectory(); break;
00427 case 1:
00428 if (_settings_game.economy.found_town != TF_FORBIDDEN) ShowFoundTownWindow();
00429 break;
00430 }
00431 }
00432
00433
00434
00435 static void ToolbarSubsidiesClick(Window *w)
00436 {
00437 PopupMainToolbMenu(w, TBN_SUBSIDIES, STR_SUBSIDIES_MENU_SUBSIDIES, 1);
00438 }
00439
00440 static void MenuClickSubsidies(int index)
00441 {
00442 ShowSubsidiesList();
00443 }
00444
00445
00446
00447 static void ToolbarStationsClick(Window *w)
00448 {
00449 PopupMainCompanyToolbMenu(w, TBN_STATIONS);
00450 }
00451
00452 static void MenuClickStations(int index)
00453 {
00454 ShowCompanyStations((CompanyID)index);
00455 }
00456
00457
00458
00459 static void ToolbarFinancesClick(Window *w)
00460 {
00461 PopupMainCompanyToolbMenu(w, TBN_FINANCES);
00462 }
00463
00464 static void MenuClickFinances(int index)
00465 {
00466 ShowCompanyFinances((CompanyID)index);
00467 }
00468
00469
00470
00471 static void ToolbarCompaniesClick(Window *w)
00472 {
00473 PopupMainCompanyToolbMenu(w, TBN_COMPANIES);
00474 }
00475
00476 static void MenuClickCompany(int index)
00477 {
00478 #ifdef ENABLE_NETWORK
00479 if (_networking) {
00480 switch (index) {
00481 case CTMN_CLIENT_LIST:
00482 ShowClientList();
00483 return;
00484
00485 case CTMN_NEW_COMPANY:
00486 if (_network_server) {
00487 DoCommandP(0, 0, _network_own_client_id, CMD_COMPANY_CTRL);
00488 } else {
00489 NetworkSend_Command(0, 0, 0, CMD_COMPANY_CTRL, NULL, NULL);
00490 }
00491 return;
00492
00493 case CTMN_SPECTATE:
00494 if (_network_server) {
00495 NetworkServerDoMove(CLIENT_ID_SERVER, COMPANY_SPECTATOR);
00496 MarkWholeScreenDirty();
00497 } else {
00498 NetworkClientRequestMove(COMPANY_SPECTATOR);
00499 }
00500 return;
00501 }
00502 }
00503 #endif
00504 ShowCompany((CompanyID)index);
00505 }
00506
00507
00508
00509 static void ToolbarGraphsClick(Window *w)
00510 {
00511 PopupMainToolbMenu(w, TBN_GRAPHICS, STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH, (_toolbar_mode == TB_NORMAL) ? 6 : 8);
00512 }
00513
00514 static void MenuClickGraphs(int index)
00515 {
00516 switch (index) {
00517 case 0: ShowOperatingProfitGraph(); break;
00518 case 1: ShowIncomeGraph(); break;
00519 case 2: ShowDeliveredCargoGraph(); break;
00520 case 3: ShowPerformanceHistoryGraph(); break;
00521 case 4: ShowCompanyValueGraph(); break;
00522 case 5: ShowCargoPaymentRates(); break;
00523
00524 case 6: ShowCompanyLeagueTable(); break;
00525 case 7: ShowPerformanceRatingDetail(); break;
00526 }
00527 }
00528
00529
00530
00531 static void ToolbarLeagueClick(Window *w)
00532 {
00533 PopupMainToolbMenu(w, TBN_LEAGUE, STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE, 2);
00534 }
00535
00536 static void MenuClickLeague(int index)
00537 {
00538 switch (index) {
00539 case 0: ShowCompanyLeagueTable(); break;
00540 case 1: ShowPerformanceRatingDetail(); break;
00541 }
00542 }
00543
00544
00545
00546 static void ToolbarIndustryClick(Window *w)
00547 {
00548
00549 PopupMainToolbMenu(w, TBN_INDUSTRIES, STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY, (_local_company == COMPANY_SPECTATOR) ? 1 : 2);
00550 }
00551
00552 static void MenuClickIndustry(int index)
00553 {
00554 switch (index) {
00555 case 0: ShowIndustryDirectory(); break;
00556 case 1: ShowBuildIndustryWindow(); break;
00557 }
00558 }
00559
00560
00561
00562 static void ToolbarVehicleClick(Window *w, VehicleType veh)
00563 {
00564 const Vehicle *v;
00565 int dis = ~0;
00566
00567 FOR_ALL_VEHICLES(v) {
00568 if (v->type == veh && v->IsPrimaryVehicle()) ClrBit(dis, v->owner);
00569 }
00570 PopupMainCompanyToolbMenu(w, TBN_VEHICLESTART + veh, dis);
00571 }
00572
00573
00574 static void ToolbarTrainClick(Window *w)
00575 {
00576 ToolbarVehicleClick(w, VEH_TRAIN);
00577 }
00578
00579 static void MenuClickShowTrains(int index)
00580 {
00581 ShowVehicleListWindow((CompanyID)index, VEH_TRAIN);
00582 }
00583
00584
00585
00586 static void ToolbarRoadClick(Window *w)
00587 {
00588 ToolbarVehicleClick(w, VEH_ROAD);
00589 }
00590
00591 static void MenuClickShowRoad(int index)
00592 {
00593 ShowVehicleListWindow((CompanyID)index, VEH_ROAD);
00594 }
00595
00596
00597
00598 static void ToolbarShipClick(Window *w)
00599 {
00600 ToolbarVehicleClick(w, VEH_SHIP);
00601 }
00602
00603 static void MenuClickShowShips(int index)
00604 {
00605 ShowVehicleListWindow((CompanyID)index, VEH_SHIP);
00606 }
00607
00608
00609
00610 static void ToolbarAirClick(Window *w)
00611 {
00612 ToolbarVehicleClick(w, VEH_AIRCRAFT);
00613 }
00614
00615 static void MenuClickShowAir(int index)
00616 {
00617 ShowVehicleListWindow((CompanyID)index, VEH_AIRCRAFT);
00618 }
00619
00620
00621
00622 static void ToolbarZoomInClick(Window *w)
00623 {
00624 if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) {
00625 w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)TBSE_ZOOMIN : (byte)TBN_ZOOMIN);
00626 SndPlayFx(SND_15_BEEP);
00627 }
00628 }
00629
00630
00631
00632 static void ToolbarZoomOutClick(Window *w)
00633 {
00634 if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) {
00635 w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)TBSE_ZOOMOUT : (byte)TBN_ZOOMOUT);
00636 SndPlayFx(SND_15_BEEP);
00637 }
00638 }
00639
00640
00641
00642 static void ToolbarBuildRailClick(Window *w)
00643 {
00644 const Company *c = Company::Get(_local_company);
00645 DropDownList *list = new DropDownList();
00646 for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
00647 const RailtypeInfo *rti = GetRailTypeInfo(rt);
00648
00649 if (rti->label == 0) continue;
00650 list->push_back(new DropDownListStringItem(rti->strings.menu_text, rt, !HasBit(c->avail_railtypes, rt)));
00651 }
00652 ShowDropDownList(w, list, _last_built_railtype, TBN_RAILS, 140, true, true);
00653 SndPlayFx(SND_15_BEEP);
00654 }
00655
00656 static void MenuClickBuildRail(int index)
00657 {
00658 _last_built_railtype = (RailType)index;
00659 ShowBuildRailToolbar(_last_built_railtype, -1);
00660 }
00661
00662
00663
00664 static void ToolbarBuildRoadClick(Window *w)
00665 {
00666 const Company *c = Company::Get(_local_company);
00667 DropDownList *list = new DropDownList();
00668 for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
00669
00670 list->push_back(new DropDownListStringItem(STR_ROAD_MENU_ROAD_CONSTRUCTION + rt, rt, !(HasBit(c->avail_roadtypes, rt) || rt == ROADTYPE_ROAD)));
00671 }
00672 ShowDropDownList(w, list, _last_built_roadtype, TBN_ROADS, 140, true, true);
00673 SndPlayFx(SND_15_BEEP);
00674 }
00675
00676 static void MenuClickBuildRoad(int index)
00677 {
00678 _last_built_roadtype = (RoadType)index;
00679 ShowBuildRoadToolbar(_last_built_roadtype);
00680 }
00681
00682
00683
00684 static void ToolbarBuildWaterClick(Window *w)
00685 {
00686 PopupMainToolbMenu(w, TBN_WATER, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 1);
00687 }
00688
00689 static void MenuClickBuildWater(int index)
00690 {
00691 ShowBuildDocksToolbar();
00692 }
00693
00694
00695
00696 static void ToolbarBuildAirClick(Window *w)
00697 {
00698 PopupMainToolbMenu(w, TBN_AIR, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 1);
00699 }
00700
00701 static void MenuClickBuildAir(int index)
00702 {
00703 ShowBuildAirToolbar();
00704 }
00705
00706
00707
00708 static void ToolbarForestClick(Window *w)
00709 {
00710 PopupMainToolbMenu(w, TBN_LANDSCAPE, STR_LANDSCAPING_MENU_LANDSCAPING, 3);
00711 }
00712
00713 static void MenuClickForest(int index)
00714 {
00715 switch (index) {
00716 case 0: ShowTerraformToolbar(); break;
00717 case 1: ShowBuildTreesToolbar(); break;
00718 case 2: SelectSignTool(); break;
00719 }
00720 }
00721
00722
00723
00724 static void ToolbarMusicClick(Window *w)
00725 {
00726 PopupMainToolbMenu(w, TBN_MUSICSOUND, STR_TOOLBAR_SOUND_MUSIC, 1);
00727 }
00728
00729 static void MenuClickMusicWindow(int index)
00730 {
00731 ShowMusicWindow();
00732 }
00733
00734
00735
00736 static void ToolbarNewspaperClick(Window *w)
00737 {
00738 PopupMainToolbMenu(w, TBN_NEWSREPORT, STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT, 3);
00739 }
00740
00741 static void MenuClickNewspaper(int index)
00742 {
00743 switch (index) {
00744 case 0: ShowLastNewsMessage(); break;
00745 case 1: ShowMessageOptions(); break;
00746 case 2: ShowMessageHistory(); break;
00747 }
00748 }
00749
00750
00751
00752 static void ToolbarHelpClick(Window *w)
00753 {
00754 PopupMainToolbMenu(w, TBN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, 7);
00755 }
00756
00757 static void MenuClickSmallScreenshot()
00758 {
00759 MakeScreenshot(SC_VIEWPORT, NULL);
00760 }
00761
00762 static void MenuClickWorldScreenshot()
00763 {
00764 MakeScreenshot(SC_WORLD, NULL);
00765 }
00766
00767 static void MenuClickHelp(int index)
00768 {
00769 switch (index) {
00770 case 0: PlaceLandBlockInfo(); break;
00771 case 2: IConsoleSwitch(); break;
00772 case 3: ShowAIDebugWindow(); break;
00773 case 4: MenuClickSmallScreenshot(); break;
00774 case 5: MenuClickWorldScreenshot(); break;
00775 case 6: ShowAboutWindow(); break;
00776 }
00777 }
00778
00779
00780
00781 static void ToolbarSwitchClick(Window *w)
00782 {
00783 if (_toolbar_mode != TB_LOWER) {
00784 _toolbar_mode = TB_LOWER;
00785 } else {
00786 _toolbar_mode = TB_UPPER;
00787 }
00788
00789 w->ReInit();
00790 w->SetWidgetLoweredState(TBN_SWITCHBAR, _toolbar_mode == TB_LOWER);
00791 SndPlayFx(SND_15_BEEP);
00792 }
00793
00794
00795
00796 static void ToolbarScenDateBackward(Window *w)
00797 {
00798
00799 if ((w->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
00800 w->HandleButtonClick(TBSE_DATEBACKWARD);
00801 w->SetDirty();
00802
00803 _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year - 1, MIN_YEAR, MAX_YEAR);
00804 SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
00805 }
00806 _left_button_clicked = false;
00807 }
00808
00809 static void ToolbarScenDateForward(Window *w)
00810 {
00811
00812 if ((w->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
00813 w->HandleButtonClick(TBSE_DATEFORWARD);
00814 w->SetDirty();
00815
00816 _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year + 1, MIN_YEAR, MAX_YEAR);
00817 SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
00818 }
00819 _left_button_clicked = false;
00820 }
00821
00822 static void ToolbarScenGenLand(Window *w)
00823 {
00824 w->HandleButtonClick(TBSE_LANDGENERATE);
00825 SndPlayFx(SND_15_BEEP);
00826
00827 ShowEditorTerraformToolbar();
00828 }
00829
00830
00831 static void ToolbarScenGenTown(Window *w)
00832 {
00833 w->HandleButtonClick(TBSE_TOWNGENERATE);
00834 SndPlayFx(SND_15_BEEP);
00835 ShowFoundTownWindow();
00836 }
00837
00838 static void ToolbarScenGenIndustry(Window *w)
00839 {
00840 w->HandleButtonClick(TBSE_INDUSTRYGENERATE);
00841 SndPlayFx(SND_15_BEEP);
00842 ShowBuildIndustryWindow();
00843 }
00844
00845 static void ToolbarScenBuildRoad(Window *w)
00846 {
00847 w->HandleButtonClick(TBSE_BUILDROAD);
00848 SndPlayFx(SND_15_BEEP);
00849 ShowBuildRoadScenToolbar();
00850 }
00851
00852 static void ToolbarScenBuildDocks(Window *w)
00853 {
00854 w->HandleButtonClick(TBSE_BUILDDOCKS);
00855 SndPlayFx(SND_15_BEEP);
00856 ShowBuildDocksScenToolbar();
00857 }
00858
00859 static void ToolbarScenPlantTrees(Window *w)
00860 {
00861 w->HandleButtonClick(TBSE_PLANTTREES);
00862 SndPlayFx(SND_15_BEEP);
00863 ShowBuildTreesToolbar();
00864 }
00865
00866 static void ToolbarScenPlaceSign(Window *w)
00867 {
00868 w->HandleButtonClick(TBSE_PLACESIGNS);
00869 SndPlayFx(SND_15_BEEP);
00870 SelectSignTool();
00871 }
00872
00873 static void ToolbarBtn_NULL(Window *w)
00874 {
00875 }
00876
00877 typedef void MenuClickedProc(int index);
00878
00879 static MenuClickedProc * const _menu_clicked_procs[] = {
00880 NULL,
00881 NULL,
00882 MenuClickSettings,
00883 MenuClickSaveLoad,
00884 MenuClickMap,
00885 MenuClickTown,
00886 MenuClickSubsidies,
00887 MenuClickStations,
00888 MenuClickFinances,
00889 MenuClickCompany,
00890 MenuClickGraphs,
00891 MenuClickLeague,
00892 MenuClickIndustry,
00893 MenuClickShowTrains,
00894 MenuClickShowRoad,
00895 MenuClickShowShips,
00896 MenuClickShowAir,
00897 MenuClickMap,
00898 NULL,
00899 MenuClickBuildRail,
00900 MenuClickBuildRoad,
00901 MenuClickBuildWater,
00902 MenuClickBuildAir,
00903 MenuClickForest,
00904 MenuClickMusicWindow,
00905 MenuClickNewspaper,
00906 MenuClickHelp,
00907 };
00908
00910 class NWidgetToolbarContainer : public NWidgetContainer {
00911 bool visible[TBN_END];
00912 protected:
00913 uint spacers;
00914
00915 public:
00916 NWidgetToolbarContainer() : NWidgetContainer(NWID_HORIZONTAL)
00917 {
00918 }
00919
00925 bool IsButton(WidgetType type) const
00926 {
00927 return type == WWT_IMGBTN || type == WWT_IMGBTN_2 || type == WWT_PUSHIMGBTN;
00928 }
00929
00930 void SetupSmallestSize(Window *w, bool init_array)
00931 {
00932 this->smallest_x = 0;
00933 this->smallest_y = 0;
00934 this->fill_x = 1;
00935 this->fill_y = 0;
00936 this->resize_x = 1;
00937 this->resize_y = 0;
00938 this->spacers = 0;
00939
00940
00941 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
00942 child_wid->SetupSmallestSize(w, init_array);
00943 this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom);
00944 if (this->IsButton(child_wid->type)) {
00945 this->smallest_x = max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right);
00946 } else if (child_wid->type == NWID_SPACER) {
00947 this->spacers++;
00948 }
00949 }
00950
00951
00952 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
00953 child_wid->current_y = this->smallest_y;
00954 if (!this->IsButton(child_wid->type)) {
00955 child_wid->current_x = child_wid->smallest_x;
00956 }
00957 }
00958 }
00959
00960 void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl)
00961 {
00962 assert(given_width >= this->smallest_x && given_height >= this->smallest_y);
00963
00964 this->pos_x = x;
00965 this->pos_y = y;
00966 this->current_x = given_width;
00967 this->current_y = given_height;
00968
00969
00970 memset(this->visible, 0, sizeof(this->visible));
00971 uint arrangable_count, button_count, spacer_count;
00972 const byte *arrangement = GetButtonArrangement(given_width, arrangable_count, button_count, spacer_count);
00973 for (uint i = 0; i < arrangable_count; i++) {
00974 this->visible[arrangement[i]] = true;
00975 }
00976
00977
00978 NWidgetBase *widgets[TBN_END];
00979 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
00980 if (child_wid->type == NWID_SPACER) continue;
00981 widgets[((NWidgetCore*)child_wid)->index] = child_wid;
00982 }
00983
00984
00985 uint position = 0;
00986 uint spacer_space = max(0, (int)given_width - (int)(button_count * this->smallest_x));
00987 uint button_space = given_width - spacer_space;
00988 uint spacer_i = 0;
00989 uint button_i = 0;
00990
00991
00992 const byte *cur_wid = rtl ? &arrangement[arrangable_count - 1] : arrangement;
00993 for (uint i = 0; i < arrangable_count; i++) {
00994 NWidgetBase *child_wid = widgets[*cur_wid];
00995
00996 if (spacer_space != 0) {
00997 NWidgetBase *possible_spacer = rtl ? child_wid->next : child_wid->prev;
00998 if (possible_spacer != NULL && possible_spacer->type == NWID_SPACER) {
00999 uint add = spacer_space / (spacer_count - spacer_i);
01000 position += add;
01001 spacer_space -= add;
01002 spacer_i++;
01003 }
01004 }
01005
01006
01007 if (this->IsButton(child_wid->type)) {
01008 child_wid->current_x = button_space / (button_count - button_i);
01009 button_space -= child_wid->current_x;
01010 button_i++;
01011 }
01012 child_wid->AssignSizePosition(sizing, x + position, y, child_wid->current_x, this->current_y, rtl);
01013 position += child_wid->current_x;
01014
01015 if (rtl) {
01016 cur_wid--;
01017 } else {
01018 cur_wid++;
01019 }
01020 }
01021 }
01022
01023 void Draw(const Window *w)
01024 {
01025
01026 GfxFillRect(this->pos_x, this->pos_y, this->pos_x + this->current_x - 1, this->pos_y + this->current_y - 1, 0xB2);
01027 GfxFillRect(this->pos_x, this->pos_y, this->pos_x + this->current_x - 1, this->pos_y + this->current_y - 1, 0xB4, FILLRECT_CHECKER);
01028
01029 bool rtl = _dynlang.text_dir == TD_RTL;
01030 for (NWidgetBase *child_wid = rtl ? this->tail : this->head; child_wid != NULL; child_wid = rtl ? child_wid->prev : child_wid->next) {
01031 if (child_wid->type == NWID_SPACER) continue;
01032 if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
01033
01034 child_wid->Draw(w);
01035 }
01036 }
01037
01038 NWidgetCore *GetWidgetFromPos(int x, int y)
01039 {
01040 if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL;
01041
01042 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01043 if (child_wid->type == NWID_SPACER) continue;
01044 if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
01045
01046 NWidgetCore *nwid = child_wid->GetWidgetFromPos(x, y);
01047 if (nwid != NULL) return nwid;
01048 }
01049 return NULL;
01050 }
01051
01060 virtual const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const = 0;
01061 };
01062
01064 class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
01065 const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
01066 {
01067 static const uint SMALLEST_ARRANGEMENT = 14;
01068 static const uint BIGGEST_ARRANGEMENT = 19;
01069 static const byte arrange14[] = {
01070 0, 1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 27,
01071 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 24, 25, 26, 27,
01072 };
01073 static const byte arrange15[] = {
01074 0, 1, 4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
01075 0, 2, 4, 3, 5, 6, 7, 8, 9, 10, 12, 24, 25, 26, 27,
01076 };
01077 static const byte arrange16[] = {
01078 0, 1, 2, 4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
01079 0, 1, 3, 5, 6, 7, 8, 9, 10, 12, 24, 25, 26, 17, 18, 27,
01080 };
01081 static const byte arrange17[] = {
01082 0, 1, 2, 4, 6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
01083 0, 1, 3, 4, 6, 5, 7, 8, 9, 10, 12, 24, 25, 26, 17, 18, 27,
01084 };
01085 static const byte arrange18[] = {
01086 0, 1, 2, 4, 5, 6, 7, 8, 9, 12, 19, 20, 21, 22, 23, 17, 18, 27,
01087 0, 1, 3, 4, 5, 6, 7, 10, 13, 14, 15, 16, 24, 25, 26, 17, 18, 27,
01088 };
01089 static const byte arrange19[] = {
01090 0, 1, 2, 4, 5, 6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 27,
01091 0, 1, 3, 4, 7, 8, 9, 10, 12, 25, 19, 20, 21, 22, 23, 26, 17, 18, 27,
01092 };
01093 static const byte arrange_all[] = {
01094 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
01095 };
01096
01097
01098 uint full_buttons = max((width + this->smallest_x - 1) / this->smallest_x, SMALLEST_ARRANGEMENT);
01099 if (full_buttons > BIGGEST_ARRANGEMENT) {
01100 button_count = arrangable_count = lengthof(arrange_all);
01101 spacer_count = this->spacers;
01102 return arrange_all;
01103 }
01104
01105
01106 static const byte * const arrangements[] = { arrange14, arrange15, arrange16, arrange17, arrange18, arrange19 };
01107
01108 button_count = arrangable_count = full_buttons;
01109 spacer_count = this->spacers;
01110 return arrangements[full_buttons - SMALLEST_ARRANGEMENT] + ((_toolbar_mode == TB_LOWER) ? full_buttons : 0);
01111 }
01112 };
01113
01115 class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer {
01116 uint panel_widths[2];
01117
01118 void SetupSmallestSize(Window *w, bool init_array)
01119 {
01120 this->NWidgetToolbarContainer::SetupSmallestSize(w, init_array);
01121
01122
01123 uint i = 0;
01124 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01125 if (child_wid->type == NWID_SPACER || this->IsButton(child_wid->type)) continue;
01126
01127 assert(i < lengthof(this->panel_widths));
01128 this->panel_widths[i++] = child_wid->current_x;
01129 }
01130 }
01131
01132 const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
01133 {
01134 static const byte arrange_all[] = {
01135 0, 1, 2, 3, 4, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24, 26,
01136 };
01137 static const byte arrange_nopanel[] = {
01138 0, 1, 2, 3, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24, 26,
01139 };
01140 static const byte arrange_switch[] = {
01141 18, 8, 11, 12, 13, 14, 15, 16, 17, 27,
01142 0, 1, 2, 3, 18, 9, 10, 24, 26, 27,
01143 };
01144
01145
01146 uint min_full_width = (lengthof(arrange_all) - lengthof(this->panel_widths)) * this->smallest_x + this->panel_widths[0] + this->panel_widths[1];
01147 if (width >= min_full_width) {
01148 width -= this->panel_widths[0] + this->panel_widths[1];
01149 arrangable_count = lengthof(arrange_all);
01150 button_count = arrangable_count - 2;
01151 spacer_count = this->spacers;
01152 return arrange_all;
01153 }
01154
01155
01156 uint min_small_width = (lengthof(arrange_switch) - lengthof(this->panel_widths)) * this->smallest_x / 2 + this->panel_widths[1];
01157 if (width > min_small_width) {
01158 width -= this->panel_widths[1];
01159 arrangable_count = lengthof(arrange_nopanel);
01160 button_count = arrangable_count - 1;
01161 spacer_count = this->spacers - 1;
01162 return arrange_nopanel;
01163 }
01164
01165
01166 width -= this->panel_widths[1];
01167 arrangable_count = lengthof(arrange_switch) / 2;
01168 button_count = arrangable_count - 1;
01169 spacer_count = 0;
01170 return arrange_switch + ((_toolbar_mode == TB_LOWER) ? arrangable_count : 0);
01171 }
01172 };
01173
01174
01175
01176 typedef void ToolbarButtonProc(Window *w);
01177
01178 static ToolbarButtonProc * const _toolbar_button_procs[] = {
01179 ToolbarPauseClick,
01180 ToolbarFastForwardClick,
01181 ToolbarOptionsClick,
01182 ToolbarSaveClick,
01183 ToolbarMapClick,
01184 ToolbarTownClick,
01185 ToolbarSubsidiesClick,
01186 ToolbarStationsClick,
01187 ToolbarFinancesClick,
01188 ToolbarCompaniesClick,
01189 ToolbarGraphsClick,
01190 ToolbarLeagueClick,
01191 ToolbarIndustryClick,
01192 ToolbarTrainClick,
01193 ToolbarRoadClick,
01194 ToolbarShipClick,
01195 ToolbarAirClick,
01196 ToolbarZoomInClick,
01197 ToolbarZoomOutClick,
01198 ToolbarBuildRailClick,
01199 ToolbarBuildRoadClick,
01200 ToolbarBuildWaterClick,
01201 ToolbarBuildAirClick,
01202 ToolbarForestClick,
01203 ToolbarMusicClick,
01204 ToolbarNewspaperClick,
01205 ToolbarHelpClick,
01206 ToolbarSwitchClick,
01207 };
01208
01209 struct MainToolbarWindow : Window {
01210 MainToolbarWindow(const WindowDesc *desc) : Window()
01211 {
01212 this->InitNested(desc, 0);
01213
01214 CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
01215 this->SetWidgetDisabledState(TBN_PAUSE, _networking && !_network_server);
01216 this->SetWidgetDisabledState(TBN_FASTFORWARD, _networking);
01217 PositionMainToolbar(this);
01218 DoZoomInOutWindow(ZOOM_NONE, this);
01219 }
01220
01221 virtual void OnPaint()
01222 {
01223
01224
01225
01226 this->SetWidgetsDisabledState(_local_company == COMPANY_SPECTATOR, TBN_RAILS, TBN_ROADS, TBN_WATER, TBN_AIR, TBN_LANDSCAPE, WIDGET_LIST_END);
01227
01228 this->SetWidgetsDisabledState(Company::GetNumItems() == 0, TBN_STATIONS, TBN_FINANCES, TBN_TRAINS, TBN_ROADVEHS, TBN_SHIPS, TBN_AIRCRAFTS, WIDGET_LIST_END);
01229
01230 this->SetWidgetDisabledState(TBN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN));
01231 this->SetWidgetDisabledState(TBN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT));
01232
01233 this->DrawWidgets();
01234 }
01235
01236 virtual void OnClick(Point pt, int widget)
01237 {
01238 if (_game_mode != GM_MENU && !this->IsWidgetDisabled(widget)) _toolbar_button_procs[widget](this);
01239 }
01240
01241 virtual void OnDropdownSelect(int widget, int index)
01242 {
01243 _menu_clicked_procs[widget](index);
01244 }
01245
01246 virtual EventState OnKeyPress(uint16 key, uint16 keycode)
01247 {
01248 switch (keycode) {
01249 case WKC_F1: case WKC_PAUSE: ToolbarPauseClick(this); break;
01250 case WKC_F2: ShowGameOptions(); break;
01251 case WKC_F3: MenuClickSaveLoad(); break;
01252 case WKC_F4: ShowSmallMap(); break;
01253 case WKC_F5: ShowTownDirectory(); break;
01254 case WKC_F6: ShowSubsidiesList(); break;
01255 case WKC_F7: ShowCompanyStations(_local_company); break;
01256 case WKC_F8: ShowCompanyFinances(_local_company); break;
01257 case WKC_F9: ShowCompany(_local_company); break;
01258 case WKC_F10: ShowOperatingProfitGraph(); break;
01259 case WKC_F11: ShowCompanyLeagueTable(); break;
01260 case WKC_F12: ShowBuildIndustryWindow(); break;
01261 case WKC_SHIFT | WKC_F1: ShowVehicleListWindow(_local_company, VEH_TRAIN); break;
01262 case WKC_SHIFT | WKC_F2: ShowVehicleListWindow(_local_company, VEH_ROAD); break;
01263 case WKC_SHIFT | WKC_F3: ShowVehicleListWindow(_local_company, VEH_SHIP); break;
01264 case WKC_SHIFT | WKC_F4: ShowVehicleListWindow(_local_company, VEH_AIRCRAFT); break;
01265 case WKC_NUM_PLUS:
01266 case WKC_EQUALS:
01267 case WKC_SHIFT | WKC_EQUALS:
01268 case WKC_SHIFT | WKC_F5: ToolbarZoomInClick(this); break;
01269 case WKC_NUM_MINUS:
01270 case WKC_MINUS:
01271 case WKC_SHIFT | WKC_MINUS:
01272 case WKC_SHIFT | WKC_F6: ToolbarZoomOutClick(this); break;
01273 case WKC_SHIFT | WKC_F7: if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype, -1); break;
01274 case WKC_SHIFT | WKC_F8: ShowBuildRoadToolbar(_last_built_roadtype); break;
01275 case WKC_SHIFT | WKC_F9: ShowBuildDocksToolbar(); break;
01276 case WKC_SHIFT | WKC_F10: if (CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) ShowBuildAirToolbar(); break;
01277 case WKC_SHIFT | WKC_F11: ShowBuildTreesToolbar(); break;
01278 case WKC_SHIFT | WKC_F12: ShowMusicWindow(); break;
01279 case WKC_CTRL | 'S': MenuClickSmallScreenshot(); break;
01280 case WKC_CTRL | 'G': MenuClickWorldScreenshot(); break;
01281 case WKC_CTRL | WKC_ALT | 'C': if (!_networking) ShowCheatWindow(); break;
01282 case 'A': if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype, 4); break;
01283 case 'L': ShowTerraformToolbar(); break;
01284 case 'Q': case 'W': case 'E': case 'D': ShowTerraformToolbarWithTool(key, keycode); break;
01285 case 'M': ShowSmallMap(); break;
01286 case 'V': ShowExtraViewPortWindow(); break;
01287 default: return ES_NOT_HANDLED;
01288 }
01289 return ES_HANDLED;
01290 }
01291
01292 virtual void OnPlaceObject(Point pt, TileIndex tile)
01293 {
01294 _place_proc(tile);
01295 }
01296
01297 virtual void OnTick()
01298 {
01299 if (this->IsWidgetLowered(TBN_PAUSE) != !!_pause_mode) {
01300 this->ToggleWidgetLoweredState(TBN_PAUSE);
01301 this->SetWidgetDirty(TBN_PAUSE);
01302 }
01303
01304 if (this->IsWidgetLowered(TBN_FASTFORWARD) != !!_fast_forward) {
01305 this->ToggleWidgetLoweredState(TBN_FASTFORWARD);
01306 this->SetWidgetDirty(TBN_FASTFORWARD);
01307 }
01308 }
01309
01310 virtual void OnTimeout()
01311 {
01312
01313
01314 for (uint i = TBN_SETTINGS; i < TBN_SWITCHBAR; i++) {
01315 if (this->IsWidgetLowered(i)) {
01316 this->RaiseWidget(i);
01317 this->SetWidgetDirty(i);
01318 }
01319 }
01320 }
01321
01322 virtual void OnInvalidateData(int data)
01323 {
01324 if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, TBN_ZOOMIN, TBN_ZOOMOUT);
01325 }
01326 };
01327
01328 static NWidgetBase *MakeMainToolbar(int *biggest_index)
01329 {
01331 static const SpriteID toolbar_button_sprites[] = {
01332 SPR_IMG_PAUSE,
01333 SPR_IMG_FASTFORWARD,
01334 SPR_IMG_SETTINGS,
01335 SPR_IMG_SAVE,
01336 SPR_IMG_SMALLMAP,
01337 SPR_IMG_TOWN,
01338 SPR_IMG_SUBSIDIES,
01339 SPR_IMG_COMPANY_LIST,
01340 SPR_IMG_COMPANY_FINANCE,
01341 SPR_IMG_COMPANY_GENERAL,
01342 SPR_IMG_GRAPHS,
01343 SPR_IMG_COMPANY_LEAGUE,
01344 SPR_IMG_INDUSTRY,
01345 SPR_IMG_TRAINLIST,
01346 SPR_IMG_TRUCKLIST,
01347 SPR_IMG_SHIPLIST,
01348 SPR_IMG_AIRPLANESLIST,
01349 SPR_IMG_ZOOMIN,
01350 SPR_IMG_ZOOMOUT,
01351 SPR_IMG_BUILDRAIL,
01352 SPR_IMG_BUILDROAD,
01353 SPR_IMG_BUILDWATER,
01354 SPR_IMG_BUILDAIR,
01355 SPR_IMG_LANDSCAPING,
01356 SPR_IMG_MUSIC,
01357 SPR_IMG_MESSAGES,
01358 SPR_IMG_QUERY,
01359 SPR_IMG_SWITCH_TOOLBAR,
01360 };
01361
01362 NWidgetMainToolbarContainer *hor = new NWidgetMainToolbarContainer();
01363 for (uint i = 0; i < TBN_END; i++) {
01364 switch (i) {
01365 case 4: case 8: case 13: case 17: case 19: case 24: hor->Add(new NWidgetSpacer(0, 0)); break;
01366 }
01367 hor->Add(new NWidgetLeaf(i == TBN_SAVEGAME ? WWT_IMGBTN_2 : WWT_IMGBTN, COLOUR_GREY, i, toolbar_button_sprites[i], STR_TOOLBAR_TOOLTIP_PAUSE_GAME + i));
01368 }
01369
01370 *biggest_index = max<int>(*biggest_index, TBN_SWITCHBAR);
01371 return hor;
01372 }
01373
01374 static const NWidgetPart _nested_toolbar_normal_widgets[] = {
01375 NWidgetFunction(MakeMainToolbar),
01376 };
01377
01378 static const WindowDesc _toolb_normal_desc(
01379 WDP_MANUAL, 640, 22,
01380 WC_MAIN_TOOLBAR, WC_NONE,
01381 WDF_NO_FOCUS,
01382 _nested_toolbar_normal_widgets, lengthof(_nested_toolbar_normal_widgets)
01383 );
01384
01385
01386
01387
01388 static ToolbarButtonProc * const _scen_toolbar_button_procs[] = {
01389 ToolbarPauseClick,
01390 ToolbarFastForwardClick,
01391 ToolbarOptionsClick,
01392 ToolbarScenSaveOrLoad,
01393 ToolbarBtn_NULL,
01394 ToolbarBtn_NULL,
01395 ToolbarScenDateBackward,
01396 ToolbarScenDateForward,
01397 ToolbarScenMapTownDir,
01398 ToolbarZoomInClick,
01399 ToolbarZoomOutClick,
01400 ToolbarScenGenLand,
01401 ToolbarScenGenTown,
01402 ToolbarScenGenIndustry,
01403 ToolbarScenBuildRoad,
01404 ToolbarScenBuildDocks,
01405 ToolbarScenPlantTrees,
01406 ToolbarScenPlaceSign,
01407 ToolbarBtn_NULL,
01408 NULL,
01409 NULL,
01410 NULL,
01411 NULL,
01412 NULL,
01413 ToolbarMusicClick,
01414 NULL,
01415 ToolbarHelpClick,
01416 ToolbarSwitchClick,
01417 };
01418
01419 struct ScenarioEditorToolbarWindow : Window {
01420 public:
01421 ScenarioEditorToolbarWindow(const WindowDesc *desc) : Window()
01422 {
01423 this->InitNested(desc, 0);
01424
01425 CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
01426 PositionMainToolbar(this);
01427 DoZoomInOutWindow(ZOOM_NONE, this);
01428 }
01429
01430 virtual void OnPaint()
01431 {
01432 this->SetWidgetDisabledState(TBSE_DATEBACKWARD, _settings_game.game_creation.starting_year <= MIN_YEAR);
01433 this->SetWidgetDisabledState(TBSE_DATEFORWARD, _settings_game.game_creation.starting_year >= MAX_YEAR);
01434
01435 this->DrawWidgets();
01436 }
01437
01438 virtual void DrawWidget(const Rect &r, int widget) const
01439 {
01440 switch (widget) {
01441 case TBSE_DATEPANEL:
01442 SetDParam(0, ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
01443 DrawString(r.left, r.right, (this->height - FONT_HEIGHT_NORMAL) / 2, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_CENTER);
01444 break;
01445
01446 case TBSE_SPACERPANEL: {
01447 int height = r.bottom - r.top;
01448 if (height > 2 * FONT_HEIGHT_NORMAL) {
01449 DrawString(r.left, r.right, (height + 1) / 2 - FONT_HEIGHT_NORMAL, STR_SCENEDIT_TOOLBAR_OPENTTD, TC_FROMSTRING, SA_CENTER);
01450 DrawString(r.left, r.right, (height + 1) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_CENTER);
01451 } else {
01452 DrawString(r.left, r.right, (height - FONT_HEIGHT_NORMAL) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_CENTER);
01453 }
01454 } break;
01455 }
01456 }
01457
01458 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
01459 {
01460 switch (widget) {
01461 case TBSE_SPACERPANEL:
01462 size->width = max(GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_OPENTTD).width, GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR).width) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
01463 break;
01464
01465 case TBSE_DATEPANEL:
01466 SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1));
01467 *size = GetStringBoundingBox(STR_WHITE_DATE_LONG);
01468 size->height = max(size->height, GetSpriteSize(SPR_IMG_SAVE).height + WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM);
01469 break;
01470 }
01471 }
01472
01473 virtual void OnClick(Point pt, int widget)
01474 {
01475 if (_game_mode == GM_MENU) return;
01476 _scen_toolbar_button_procs[widget](this);
01477 }
01478
01479 virtual void OnDropdownSelect(int widget, int index)
01480 {
01481
01482
01483 if (widget == TBSE_SMALLMAP) widget = TBN_SMALLMAP;
01484 _menu_clicked_procs[widget](index);
01485 SndPlayFx(SND_15_BEEP);
01486 }
01487
01488 virtual EventState OnKeyPress(uint16 key, uint16 keycode)
01489 {
01490 switch (keycode) {
01491 case WKC_F1: case WKC_PAUSE: ToolbarPauseClick(this); break;
01492 case WKC_F2: ShowGameOptions(); break;
01493 case WKC_F3: MenuClickSaveLoad(); break;
01494 case WKC_F4: ToolbarScenGenLand(this); break;
01495 case WKC_F5: ToolbarScenGenTown(this); break;
01496 case WKC_F6: ToolbarScenGenIndustry(this); break;
01497 case WKC_F7: ToolbarScenBuildRoad(this); break;
01498 case WKC_F8: ToolbarScenBuildDocks(this); break;
01499 case WKC_F9: ToolbarScenPlantTrees(this); break;
01500 case WKC_F10: ToolbarScenPlaceSign(this); break;
01501 case WKC_F11: ShowMusicWindow(); break;
01502 case WKC_F12: PlaceLandBlockInfo(); break;
01503 case WKC_CTRL | 'S': MenuClickSmallScreenshot(); break;
01504 case WKC_CTRL | 'G': MenuClickWorldScreenshot(); break;
01505
01506
01507 case WKC_NUM_PLUS:
01508 case WKC_EQUALS:
01509 case WKC_SHIFT | WKC_EQUALS:
01510 case WKC_SHIFT | WKC_F5: ToolbarZoomInClick(this); break;
01511
01512
01513 case WKC_NUM_MINUS:
01514 case WKC_MINUS:
01515 case WKC_SHIFT | WKC_MINUS:
01516 case WKC_SHIFT | WKC_F6: ToolbarZoomOutClick(this); break;
01517
01518 case 'L': ShowEditorTerraformToolbar(); break;
01519 case 'Q': case 'W': case 'E': case 'D': ShowEditorTerraformToolbarWithTool(key, keycode); break;
01520 case 'M': ShowSmallMap(); break;
01521 case 'V': ShowExtraViewPortWindow(); break;
01522 default: return ES_NOT_HANDLED;
01523 }
01524 return ES_HANDLED;
01525 }
01526
01527 virtual void OnPlaceObject(Point pt, TileIndex tile)
01528 {
01529 _place_proc(tile);
01530 }
01531
01532 virtual void OnTimeout()
01533 {
01534 this->SetWidgetsLoweredState(false, TBSE_DATEBACKWARD, TBSE_DATEFORWARD, WIDGET_LIST_END);
01535 this->SetWidgetDirty(TBSE_DATEBACKWARD);
01536 this->SetWidgetDirty(TBSE_DATEFORWARD);
01537 }
01538
01539 virtual void OnTick()
01540 {
01541 if (this->IsWidgetLowered(TBSE_PAUSE) != !!_pause_mode) {
01542 this->ToggleWidgetLoweredState(TBSE_PAUSE);
01543 this->SetDirty();
01544 }
01545
01546 if (this->IsWidgetLowered(TBSE_FASTFORWARD) != !!_fast_forward) {
01547 this->ToggleWidgetLoweredState(TBSE_FASTFORWARD);
01548 this->SetDirty();
01549 }
01550 }
01551
01552 virtual void OnInvalidateData(int data)
01553 {
01554 if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, TBSE_ZOOMIN, TBSE_ZOOMOUT);
01555 }
01556 };
01557
01558 static const NWidgetPart _nested_toolb_scen_inner_widgets[] = {
01559 NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_PAUSE), SetDataTip(SPR_IMG_PAUSE, STR_TOOLBAR_TOOLTIP_PAUSE_GAME),
01560 NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_FASTFORWARD), SetDataTip(SPR_IMG_FASTFORWARD, STR_TOOLBAR_TOOLTIP_FORWARD),
01561 NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_SETTINGS), SetDataTip(SPR_IMG_SETTINGS, STR_TOOLBAR_TOOLTIP_OPTIONS),
01562 NWidget(WWT_IMGBTN_2, COLOUR_GREY, TBSE_SAVESCENARIO), SetDataTip(SPR_IMG_SAVE, STR_SCENEDIT_TOOLBAR_TOOLTIP_SAVE_SCENARIO_LOAD_SCENARIO),
01563 NWidget(NWID_SPACER),
01564 NWidget(WWT_PANEL, COLOUR_GREY, TBSE_SPACERPANEL), EndContainer(),
01565 NWidget(NWID_SPACER),
01566 NWidget(WWT_PANEL, COLOUR_GREY, TBSE_DATEPANEL_CONTAINER),
01567 NWidget(NWID_HORIZONTAL), SetPIP(3, 2, 3),
01568 NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_DATEBACKWARD), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD),
01569 NWidget(WWT_EMPTY, COLOUR_GREY, TBSE_DATEPANEL),
01570 NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_DATEFORWARD), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD),
01571 EndContainer(),
01572 EndContainer(),
01573 NWidget(NWID_SPACER),
01574 NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_SMALLMAP), SetDataTip(SPR_IMG_SMALLMAP, STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY),
01575 NWidget(NWID_SPACER),
01576 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_ZOOMIN), SetDataTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN),
01577 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_ZOOMOUT), SetDataTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT),
01578 NWidget(NWID_SPACER),
01579 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_LANDGENERATE), SetDataTip(SPR_IMG_LANDSCAPING, STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION),
01580 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_TOWNGENERATE), SetDataTip(SPR_IMG_TOWN, STR_SCENEDIT_TOOLBAR_TOWN_GENERATION),
01581 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_INDUSTRYGENERATE), SetDataTip(SPR_IMG_INDUSTRY, STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION),
01582 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_BUILDROAD), SetDataTip(SPR_IMG_BUILDROAD, STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION),
01583 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_BUILDDOCKS), SetDataTip(SPR_IMG_BUILDWATER, STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS),
01584 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_PLANTTREES), SetDataTip(SPR_IMG_PLANTTREES, STR_SCENEDIT_TOOLBAR_PLANT_TREES),
01585 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_PLACESIGNS), SetDataTip(SPR_IMG_SIGN, STR_SCENEDIT_TOOLBAR_PLACE_SIGN),
01586 NWidget(NWID_SPACER),
01587 NWidget(WWT_IMGBTN, COLOUR_GREY, TBN_MUSICSOUND), SetDataTip(SPR_IMG_MUSIC, STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW),
01588 NWidget(WWT_IMGBTN, COLOUR_GREY, TBN_HELP), SetDataTip(SPR_IMG_QUERY, STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION),
01589 NWidget(WWT_IMGBTN, COLOUR_GREY, TBN_SWITCHBAR), SetDataTip(SPR_IMG_SWITCH_TOOLBAR, STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR),
01590 };
01591
01592 static NWidgetBase *MakeScenarioToolbar(int *biggest_index)
01593 {
01594 return MakeNWidgets(_nested_toolb_scen_inner_widgets, lengthof(_nested_toolb_scen_inner_widgets), biggest_index, new NWidgetScenarioToolbarContainer());
01595 }
01596
01597 static const NWidgetPart _nested_toolb_scen_widgets[] = {
01598 NWidgetFunction(MakeScenarioToolbar),
01599 };
01600
01601 static const WindowDesc _toolb_scen_desc(
01602 WDP_MANUAL, 640, 22,
01603 WC_MAIN_TOOLBAR, WC_NONE,
01604 WDF_UNCLICK_BUTTONS | WDF_NO_FOCUS,
01605 _nested_toolb_scen_widgets, lengthof(_nested_toolb_scen_widgets)
01606 );
01607
01608
01609
01610 void AllocateToolbar()
01611 {
01612
01613 _last_built_roadtype = ROADTYPE_ROAD;
01614
01615 if (_game_mode == GM_EDITOR) {
01616 new ScenarioEditorToolbarWindow(&_toolb_scen_desc);;
01617 } else {
01618 new MainToolbarWindow(&_toolb_normal_desc);
01619 }
01620 }