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