toolbar_gui.cpp

Go to the documentation of this file.
00001 /* $Id: toolbar_gui.cpp 14754 2008-12-28 14:37:19Z rubidium $ */
00002 
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "gui.h"
00008 #include "window_gui.h"
00009 #include "window_func.h"
00010 #include "viewport_func.h"
00011 #include "command_func.h"
00012 #include "variables.h"
00013 #include "train.h"
00014 #include "roadveh.h"
00015 #include "vehicle_gui.h"
00016 #include "rail_gui.h"
00017 #include "road_gui.h"
00018 #include "date_func.h"
00019 #include "vehicle_func.h"
00020 #include "sound_func.h"
00021 #include "terraform_gui.h"
00022 #include "transparency.h"
00023 #include "strings_func.h"
00024 #include "company_base.h"
00025 #include "company_func.h"
00026 #include "company_gui.h"
00027 #include "settings_type.h"
00028 #include "toolbar_gui.h"
00029 #include "vehicle_base.h"
00030 #include "gfx_func.h"
00031 #include "cheat_func.h"
00032 #include "transparency_gui.h"
00033 #include "screenshot.h"
00034 #include "newgrf_config.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 "tilehighlight_func.h"
00041 #include "rail.h"
00042 #include "widgets/dropdown_func.h"
00043 #include "widgets/dropdown_type.h"
00044 
00045 #include "network/network.h"
00046 #include "network/network_gui.h"
00047 
00048 #include "table/strings.h"
00049 #include "table/sprites.h"
00050 
00051 static void SplitToolbar(Window *w);
00052 
00053 RailType _last_built_railtype;
00054 RoadType _last_built_roadtype;
00055 
00057 enum ToolBarProperties {
00058   TBP_BUTTONWIDTH        =  22,  
00059   TBP_BUTTONHEIGHT       =  22,  
00060   TBP_DATEPANELWIDTH     = 130,  
00061 
00062   TBP_TOOLBAR_MINBUTTON  =  14,  
00063   TBP_NORMAL_MAXBUTTON   =  19,  
00064   TBP_SCENARIO_MAXBUTTON =  16,  
00065 };
00066 
00067 enum ToolbarMode {
00068   TB_NORMAL,
00069   TB_UPPER,
00070   TB_LOWER
00071 };
00072 
00073 enum ToolbarNormalWidgets {
00074   TBN_PAUSE         = 0,
00075   TBN_FASTFORWARD,
00076   TBN_SETTINGS,
00077   TBN_SAVEGAME,
00078   TBN_SMALLMAP,
00079   TBN_TOWNDIRECTORY,
00080   TBN_SUBSIDIES,
00081   TBN_STATIONS,
00082   TBN_FINANCES,
00083   TBN_COMPANIES,
00084   TBN_GRAPHICS,
00085   TBN_LEAGUE,
00086   TBN_INDUSTRIES,
00087   TBN_VEHICLESTART,      
00088   TBN_TRAINS        = TBN_VEHICLESTART,
00089   TBN_ROADVEHS,
00090   TBN_SHIPS,
00091   TBN_AIRCRAFTS,
00092   TBN_ZOOMIN,
00093   TBN_ZOOMOUT,
00094   TBN_RAILS,
00095   TBN_ROADS,
00096   TBN_WATER,
00097   TBN_AIR,
00098   TBN_LANDSCAPE,
00099   TBN_MUSICSOUND,
00100   TBN_NEWSREPORT,
00101   TBN_HELP,
00102   TBN_SWITCHBAR,         
00103 };
00104 
00105 enum ToolbarScenEditorWidgets {
00106   TBSE_PAUSE        = 0,
00107   TBSE_FASTFORWARD,
00108   TBSE_SAVESCENARIO = 3,
00109   TBSE_SPACERPANEL,
00110   TBSE_DATEPANEL,
00111   TBSE_DATEBACKWARD,
00112   TBSE_DATEFORWARD,
00113   TBSE_SMALLMAP,
00114   TBSE_ZOOMIN,
00115   TBSE_ZOOMOUT,
00116   TBSE_LANDGENERATE,
00117   TBSE_TOWNGENERATE,
00118   TBSE_INDUSTRYGENERATE,
00119   TBSE_BUILDROAD,
00120   TBSE_BUILDDOCKS,
00121   TBSE_PLANTTREES,
00122   TBSE_PLACESIGNS,
00123 };
00124 
00128 class DropDownListCheckedItem : public DropDownListStringItem {
00129 public:
00130   bool checked;
00131 
00132   DropDownListCheckedItem(StringID string, int result, bool masked, bool checked) : DropDownListStringItem(string, result, masked), checked(checked) {}
00133 
00134   virtual ~DropDownListCheckedItem() {}
00135 
00136   void Draw(int x, int y, uint width, uint height, bool sel, int bg_colour) const
00137   {
00138     if (checked) {
00139       DrawString(x + 2, y, STR_CHECKMARK, sel ? TC_WHITE : TC_BLACK);
00140     }
00141     DrawStringTruncated(x + 2, y, this->String(), sel ? TC_WHITE : TC_BLACK, width);
00142   }
00143 };
00144 
00148 class DropDownListCompanyItem : public DropDownListItem {
00149 public:
00150   bool greyed;
00151 
00152   DropDownListCompanyItem(int result, bool masked, bool greyed) : DropDownListItem(result, masked), greyed(greyed) {}
00153 
00154   virtual ~DropDownListCompanyItem() {}
00155 
00156   bool Selectable() const
00157   {
00158     return true;
00159   }
00160 
00161   uint Width() const
00162   {
00163     char buffer[512];
00164     CompanyID company = (CompanyID)result;
00165     SetDParam(0, company);
00166     SetDParam(1, company);
00167     GetString(buffer, STR_7021, lastof(buffer));
00168     return GetStringBoundingBox(buffer).width + 19;
00169   }
00170 
00171   void Draw(int x, int y, uint width, uint height, bool sel, int bg_colour) const
00172   {
00173     CompanyID company = (CompanyID)result;
00174     DrawCompanyIcon(company, x + 2, y + 1);
00175 
00176     SetDParam(0, company);
00177     SetDParam(1, company);
00178     int col;
00179     if (this->greyed) {
00180       col = TC_GREY;
00181     } else {
00182       col = sel ? TC_WHITE : TC_BLACK;
00183     }
00184     DrawStringTruncated(x + 19, y, STR_7021, col, width - 17);
00185   }
00186 };
00187 
00191 static void PopupMainToolbMenu(Window *w, int widget, StringID string, int count)
00192 {
00193   DropDownList *list = new DropDownList();
00194   for (int i = 0; i < count; i++) {
00195     list->push_back(new DropDownListStringItem(string + i, i, false));
00196   }
00197   ShowDropDownList(w, list, 0, widget, 140, true, true);
00198   SndPlayFx(SND_15_BEEP);
00199 }
00200 
00204 static void PopupMainCompanyToolbMenu(Window *w, int widget, int grey = 0)
00205 {
00206   DropDownList *list = new DropDownList();
00207 
00208   if (widget == TBN_COMPANIES && _networking) {
00209     /* Add the client list button for the companies menu */
00210     list->push_back(new DropDownListStringItem(STR_NETWORK_CLIENT_LIST, -1, false));
00211   }
00212 
00213   for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
00214     if (!IsValidCompanyID(c)) continue;
00215     list->push_back(new DropDownListCompanyItem(c, false, HasBit(grey, c)));
00216   }
00217 
00218   ShowDropDownList(w, list, _local_company == COMPANY_SPECTATOR ? -1 : _local_company, widget, 240, true, true);
00219   SndPlayFx(SND_15_BEEP);
00220 }
00221 
00222 
00223 static ToolbarMode _toolbar_mode;
00224 
00225 static void SelectSignTool()
00226 {
00227   if (_cursor.sprite == SPR_CURSOR_SIGN) {
00228     ResetObjectToPlace();
00229   } else {
00230     SetObjectToPlace(SPR_CURSOR_SIGN, PAL_NONE, VHM_RECT, WC_MAIN_TOOLBAR, 0);
00231     _place_proc = PlaceProc_Sign;
00232   }
00233 }
00234 
00235 /* --- Pausing --- */
00236 
00237 static void ToolbarPauseClick(Window *w)
00238 {
00239   if (_networking && !_network_server) return; // only server can pause the game
00240 
00241   if (DoCommandP(0, _pause_game ? 0 : 1, 0, CMD_PAUSE)) SndPlayFx(SND_15_BEEP);
00242 }
00243 
00244 /* --- Fast forwarding --- */
00245 
00246 static void ToolbarFastForwardClick(Window *w)
00247 {
00248   _fast_forward ^= true;
00249   SndPlayFx(SND_15_BEEP);
00250 }
00251 
00252 /* --- Options button menu --- */
00253 
00254 enum OptionMenuEntries {
00255   OME_GAMEOPTIONS,
00256   OME_DIFFICULTIES,
00257   OME_PATCHES,
00258   OME_NEWGRFSETTINGS,
00259   OME_TRANSPARENCIES,
00260   OME_SHOW_TOWNNAMES,
00261   OME_SHOW_STATIONNAMES,
00262   OME_SHOW_SIGNS,
00263   OME_SHOW_WAYPOINTNAMES,
00264   OME_FULL_ANIMATION,
00265   OME_FULL_DETAILS,
00266   OME_TRANSPARENTBUILDINGS,
00267   OME_SHOW_STATIONSIGNS,
00268 };
00269 
00270 static void ToolbarOptionsClick(Window *w)
00271 {
00272   DropDownList *list = new DropDownList();
00273   list->push_back(new DropDownListStringItem(STR_02C4_GAME_OPTIONS,        OME_GAMEOPTIONS, false));
00274   list->push_back(new DropDownListStringItem(STR_02C6_DIFFICULTY_SETTINGS, OME_DIFFICULTIES, false));
00275   list->push_back(new DropDownListStringItem(STR_MENU_CONFIG_PATCHES,      OME_PATCHES, false));
00276   list->push_back(new DropDownListStringItem(STR_NEWGRF_SETTINGS,          OME_NEWGRFSETTINGS, false));
00277   list->push_back(new DropDownListStringItem(STR_TRANSPARENCY_OPTIONS,     OME_TRANSPARENCIES, false));
00278   list->push_back(new DropDownListItem(-1, false));
00279   list->push_back(new DropDownListCheckedItem(STR_02CA_TOWN_NAMES_DISPLAYED,    OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES)));
00280   list->push_back(new DropDownListCheckedItem(STR_02CC_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false, HasBit(_display_opt, DO_SHOW_STATION_NAMES)));
00281   list->push_back(new DropDownListCheckedItem(STR_02CE_SIGNS_DISPLAYED,         OME_SHOW_SIGNS, false, HasBit(_display_opt, DO_SHOW_SIGNS)));
00282   list->push_back(new DropDownListCheckedItem(STR_WAYPOINTS_DISPLAYED2,         OME_SHOW_WAYPOINTNAMES, false, HasBit(_display_opt, DO_WAYPOINTS)));
00283   list->push_back(new DropDownListCheckedItem(STR_02D0_FULL_ANIMATION,          OME_FULL_ANIMATION, false, HasBit(_display_opt, DO_FULL_ANIMATION)));
00284   list->push_back(new DropDownListCheckedItem(STR_02D2_FULL_DETAIL,             OME_FULL_DETAILS, false, HasBit(_display_opt, DO_FULL_DETAIL)));
00285   list->push_back(new DropDownListCheckedItem(STR_02D4_TRANSPARENT_BUILDINGS,   OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES)));
00286   list->push_back(new DropDownListCheckedItem(STR_TRANSPARENT_SIGNS,            OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS)));
00287 
00288   ShowDropDownList(w, list, 0, TBN_SETTINGS, 140, true, true);
00289   SndPlayFx(SND_15_BEEP);
00290 }
00291 
00292 static void MenuClickSettings(int index)
00293 {
00294   switch (index) {
00295     case OME_GAMEOPTIONS:          ShowGameOptions();                              return;
00296     case OME_DIFFICULTIES:         ShowGameDifficulty();                           return;
00297     case OME_PATCHES:              ShowPatchesSelection();                         return;
00298     case OME_NEWGRFSETTINGS:       ShowNewGRFSettings(!_networking, true, true, &_grfconfig);   return;
00299     case OME_TRANSPARENCIES:       ShowTransparencyToolbar();                      break;
00300 
00301     case OME_SHOW_TOWNNAMES:       ToggleBit(_display_opt, DO_SHOW_TOWN_NAMES);    break;
00302     case OME_SHOW_STATIONNAMES:    ToggleBit(_display_opt, DO_SHOW_STATION_NAMES); break;
00303     case OME_SHOW_SIGNS:           ToggleBit(_display_opt, DO_SHOW_SIGNS);         break;
00304     case OME_SHOW_WAYPOINTNAMES:   ToggleBit(_display_opt, DO_WAYPOINTS);          break;
00305     case OME_FULL_ANIMATION:       ToggleBit(_display_opt, DO_FULL_ANIMATION);     break;
00306     case OME_FULL_DETAILS:         ToggleBit(_display_opt, DO_FULL_DETAIL);        break;
00307     case OME_TRANSPARENTBUILDINGS: ToggleTransparency(TO_HOUSES);                  break;
00308     case OME_SHOW_STATIONSIGNS:    ToggleTransparency(TO_SIGNS);                   break;
00309   }
00310   MarkWholeScreenDirty();
00311 }
00312 
00313 /* --- Saving/loading button menu --- */
00314 
00315 enum SaveLoadEditorMenuEntries {
00316   SLEME_SAVE_SCENARIO   = 0,
00317   SLEME_LOAD_SCENARIO,
00318   SLEME_LOAD_HEIGHTMAP,
00319   SLEME_EXIT_TOINTRO,
00320   SLEME_EXIT_GAME       = 5,
00321   SLEME_MENUCOUNT,
00322 };
00323 
00324 enum SaveLoadNormalMenuEntries {
00325   SLNME_SAVE_GAME   = 0,
00326   SLNME_LOAD_GAME,
00327   SLNME_EXIT_TOINTRO,
00328   SLNME_EXIT_GAME,
00329   SLNME_MENUCOUNT,
00330 };
00331 
00332 static void ToolbarSaveClick(Window *w)
00333 {
00334   PopupMainToolbMenu(w, TBN_SAVEGAME, STR_015C_SAVE_GAME, SLNME_MENUCOUNT);
00335 }
00336 
00337 static void ToolbarScenSaveOrLoad(Window *w)
00338 {
00339   PopupMainToolbMenu(w, TBSE_SAVESCENARIO, STR_0292_SAVE_SCENARIO, SLEME_MENUCOUNT);
00340 }
00341 
00342 static void MenuClickSaveLoad(int index = 0)
00343 {
00344   if (_game_mode == GM_EDITOR) {
00345     switch (index) {
00346       case SLEME_SAVE_SCENARIO:  ShowSaveLoadDialog(SLD_SAVE_SCENARIO);  break;
00347       case SLEME_LOAD_SCENARIO:  ShowSaveLoadDialog(SLD_LOAD_SCENARIO);  break;
00348       case SLEME_LOAD_HEIGHTMAP: ShowSaveLoadDialog(SLD_LOAD_HEIGHTMAP); break;
00349       case SLEME_EXIT_TOINTRO:   AskExitToGameMenu();                    break;
00350       case SLEME_EXIT_GAME:      HandleExitGameRequest();                break;
00351     }
00352   } else {
00353     switch (index) {
00354       case SLNME_SAVE_GAME:      ShowSaveLoadDialog(SLD_SAVE_GAME); break;
00355       case SLNME_LOAD_GAME:      ShowSaveLoadDialog(SLD_LOAD_GAME); break;
00356       case SLNME_EXIT_TOINTRO:   AskExitToGameMenu();               break;
00357       case SLNME_EXIT_GAME:      HandleExitGameRequest();           break;
00358     }
00359   }
00360 }
00361 
00362 /* --- Map button menu --- */
00363 
00364 enum MapMenuEntries {
00365   MME_SHOW_SMALLMAP        = 0,
00366   MME_SHOW_EXTRAVIEWPORTS,
00367   MME_SHOW_SIGNLISTS,
00368   MME_SHOW_TOWNDIRECTORY,    
00369   MME_MENUCOUNT_NORMAL     = 3,
00370   MME_MENUCOUNT_EDITOR     = 4,
00371 };
00372 
00373 static void ToolbarMapClick(Window *w)
00374 {
00375   PopupMainToolbMenu(w, TBN_SMALLMAP, STR_02DE_MAP_OF_WORLD, MME_MENUCOUNT_NORMAL);
00376 }
00377 
00378 static void ToolbarScenMapTownDir(Window *w)
00379 {
00380   PopupMainToolbMenu(w, TBSE_SMALLMAP, STR_02DE_MAP_OF_WORLD, MME_MENUCOUNT_EDITOR);
00381 }
00382 
00383 static void MenuClickMap(int index)
00384 {
00385   switch (index) {
00386     case MME_SHOW_SMALLMAP:       ShowSmallMap();            break;
00387     case MME_SHOW_EXTRAVIEWPORTS: ShowExtraViewPortWindow(); break;
00388     case MME_SHOW_SIGNLISTS:      ShowSignList();            break;
00389     case MME_SHOW_TOWNDIRECTORY:  if (_game_mode == GM_EDITOR) ShowTownDirectory(); break;
00390   }
00391 }
00392 
00393 /* --- Town button menu --- */
00394 
00395 static void ToolbarTownClick(Window *w)
00396 {
00397   PopupMainToolbMenu(w, TBN_TOWNDIRECTORY, STR_02BB_TOWN_DIRECTORY, 1);
00398 }
00399 
00400 static void MenuClickTown(int index)
00401 {
00402   ShowTownDirectory();
00403 }
00404 
00405 /* --- Subidies button menu --- */
00406 
00407 static void ToolbarSubsidiesClick(Window *w)
00408 {
00409   PopupMainToolbMenu(w, TBN_SUBSIDIES, STR_02DD_SUBSIDIES, 1);
00410 }
00411 
00412 static void MenuClickSubsidies(int index)
00413 {
00414   ShowSubsidiesList();
00415 }
00416 
00417 /* --- Stations button menu --- */
00418 
00419 static void ToolbarStationsClick(Window *w)
00420 {
00421   PopupMainCompanyToolbMenu(w, TBN_STATIONS);
00422 }
00423 
00424 static void MenuClickStations(int index)
00425 {
00426   ShowCompanyStations((CompanyID)index);
00427 }
00428 
00429 /* --- Finances button menu --- */
00430 
00431 static void ToolbarFinancesClick(Window *w)
00432 {
00433   PopupMainCompanyToolbMenu(w, TBN_FINANCES);
00434 }
00435 
00436 static void MenuClickFinances(int index)
00437 {
00438   ShowCompanyFinances((CompanyID)index);
00439 }
00440 
00441 /* --- Company's button menu --- */
00442 
00443 static void ToolbarCompaniesClick(Window *w)
00444 {
00445   PopupMainCompanyToolbMenu(w, TBN_COMPANIES);
00446 }
00447 
00448 static void MenuClickCompany(int index)
00449 {
00450   if (_networking && index == -1) {
00451     ShowClientList();
00452   } else {
00453     ShowCompany((CompanyID)index);
00454   }
00455 }
00456 
00457 /* --- Graphs button menu --- */
00458 
00459 static void ToolbarGraphsClick(Window *w)
00460 {
00461   PopupMainToolbMenu(w, TBN_GRAPHICS, STR_0154_OPERATING_PROFIT_GRAPH, (_toolbar_mode == TB_NORMAL) ? 6 : 8);
00462 }
00463 
00464 static void MenuClickGraphs(int index)
00465 {
00466   switch (index) {
00467     case 0: ShowOperatingProfitGraph();    break;
00468     case 1: ShowIncomeGraph();             break;
00469     case 2: ShowDeliveredCargoGraph();     break;
00470     case 3: ShowPerformanceHistoryGraph(); break;
00471     case 4: ShowCompanyValueGraph();       break;
00472     case 5: ShowCargoPaymentRates();       break;
00473     /* functions for combined graphs/league button */
00474     case 6: ShowCompanyLeagueTable();      break;
00475     case 7: ShowPerformanceRatingDetail(); break;
00476   }
00477 }
00478 
00479 /* --- League button menu --- */
00480 
00481 static void ToolbarLeagueClick(Window *w)
00482 {
00483   PopupMainToolbMenu(w, TBN_LEAGUE, STR_015A_COMPANY_LEAGUE_TABLE, 2);
00484 }
00485 
00486 static void MenuClickLeague(int index)
00487 {
00488   switch (index) {
00489     case 0: ShowCompanyLeagueTable();      break;
00490     case 1: ShowPerformanceRatingDetail(); break;
00491   }
00492 }
00493 
00494 /* --- Industries button menu --- */
00495 
00496 static void ToolbarIndustryClick(Window *w)
00497 {
00498   /* Disable build-industry menu if we are a spectator */
00499   PopupMainToolbMenu(w, TBN_INDUSTRIES, STR_INDUSTRY_DIR, (_current_company == COMPANY_SPECTATOR) ? 1 : 2);
00500 }
00501 
00502 static void MenuClickIndustry(int index)
00503 {
00504   switch (index) {
00505     case 0: ShowIndustryDirectory();   break;
00506     case 1: ShowBuildIndustryWindow(); break;
00507   }
00508 }
00509 
00510 /* --- Trains button menu + 1 helper function for all vehicles. --- */
00511 
00512 static void ToolbarVehicleClick(Window *w, VehicleType veh)
00513 {
00514   const Vehicle *v;
00515   int dis = ~0;
00516 
00517   FOR_ALL_VEHICLES(v) {
00518     if (v->type == veh && v->IsPrimaryVehicle()) ClrBit(dis, v->owner);
00519   }
00520   PopupMainCompanyToolbMenu(w, TBN_VEHICLESTART + veh, dis);
00521 }
00522 
00523 
00524 static void ToolbarTrainClick(Window *w)
00525 {
00526   ToolbarVehicleClick(w, VEH_TRAIN);
00527 }
00528 
00529 static void MenuClickShowTrains(int index)
00530 {
00531   ShowVehicleListWindow((CompanyID)index, VEH_TRAIN);
00532 }
00533 
00534 /* --- Road vehicle button menu --- */
00535 
00536 static void ToolbarRoadClick(Window *w)
00537 {
00538   ToolbarVehicleClick(w, VEH_ROAD);
00539 }
00540 
00541 static void MenuClickShowRoad(int index)
00542 {
00543   ShowVehicleListWindow((CompanyID)index, VEH_ROAD);
00544 }
00545 
00546 /* --- Ship button menu --- */
00547 
00548 static void ToolbarShipClick(Window *w)
00549 {
00550   ToolbarVehicleClick(w, VEH_SHIP);
00551 }
00552 
00553 static void MenuClickShowShips(int index)
00554 {
00555   ShowVehicleListWindow((CompanyID)index, VEH_SHIP);
00556 }
00557 
00558 /* --- Aircraft button menu --- */
00559 
00560 static void ToolbarAirClick(Window *w)
00561 {
00562   ToolbarVehicleClick(w, VEH_AIRCRAFT);
00563 }
00564 
00565 static void MenuClickShowAir(int index)
00566 {
00567   ShowVehicleListWindow((CompanyID)index, VEH_AIRCRAFT);
00568 }
00569 
00570 /* --- Zoom in button --- */
00571 
00572 static void ToolbarZoomInClick(Window *w)
00573 {
00574   if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) {
00575     w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)TBSE_ZOOMIN : (byte)TBN_ZOOMIN);
00576     SndPlayFx(SND_15_BEEP);
00577   }
00578 }
00579 
00580 /* --- Zoom out button --- */
00581 
00582 static void ToolbarZoomOutClick(Window *w)
00583 {
00584   if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) {
00585     w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)TBSE_ZOOMOUT : (byte)TBN_ZOOMOUT);
00586     SndPlayFx(SND_15_BEEP);
00587   }
00588 }
00589 
00590 /* --- Rail button menu --- */
00591 
00592 static void ToolbarBuildRailClick(Window *w)
00593 {
00594   const Company *c = GetCompany(_local_company);
00595   DropDownList *list = new DropDownList();
00596   for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
00597     const RailtypeInfo *rti = GetRailTypeInfo(rt);
00598     list->push_back(new DropDownListStringItem(rti->strings.menu_text, rt, !HasBit(c->avail_railtypes, rt)));
00599   }
00600   ShowDropDownList(w, list, _last_built_railtype, TBN_RAILS, 140, true, true);
00601   SndPlayFx(SND_15_BEEP);
00602 }
00603 
00604 static void MenuClickBuildRail(int index)
00605 {
00606   _last_built_railtype = (RailType)index;
00607   ShowBuildRailToolbar(_last_built_railtype, -1);
00608 }
00609 
00610 /* --- Road button menu --- */
00611 
00612 static void ToolbarBuildRoadClick(Window *w)
00613 {
00614   const Company *c = GetCompany(_local_company);
00615   DropDownList *list = new DropDownList();
00616   for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
00617     /* Highways don't exist */
00618     if (rt == ROADTYPE_HWAY) continue;
00619 
00620     /* The standard road button is *always* available */
00621     list->push_back(new DropDownListStringItem(STR_180A_ROAD_CONSTRUCTION + rt, rt, !(HasBit(c->avail_roadtypes, rt) || rt == ROADTYPE_ROAD)));
00622   }
00623   ShowDropDownList(w, list, _last_built_roadtype, TBN_ROADS, 140, true, true);
00624   SndPlayFx(SND_15_BEEP);
00625 }
00626 
00627 static void MenuClickBuildRoad(int index)
00628 {
00629   _last_built_roadtype = (RoadType)index;
00630   ShowBuildRoadToolbar(_last_built_roadtype);
00631 }
00632 
00633 /* --- Water button menu --- */
00634 
00635 static void ToolbarBuildWaterClick(Window *w)
00636 {
00637   PopupMainToolbMenu(w, TBN_WATER, STR_9800_WATERWAYS_CONSTRUCTION, 1);
00638 }
00639 
00640 static void MenuClickBuildWater(int index)
00641 {
00642   ShowBuildDocksToolbar();
00643 }
00644 
00645 /* --- Airport button menu --- */
00646 
00647 static void ToolbarBuildAirClick(Window *w)
00648 {
00649   PopupMainToolbMenu(w, TBN_AIR, STR_A01D_AIRPORT_CONSTRUCTION, 1);
00650 }
00651 
00652 static void MenuClickBuildAir(int index)
00653 {
00654   ShowBuildAirToolbar();
00655 }
00656 
00657 /* --- Forest button menu --- */
00658 
00659 static void ToolbarForestClick(Window *w)
00660 {
00661   PopupMainToolbMenu(w, TBN_LANDSCAPE, STR_LANDSCAPING, 3);
00662 }
00663 
00664 static void MenuClickForest(int index)
00665 {
00666   switch (index) {
00667     case 0: ShowTerraformToolbar();  break;
00668     case 1: ShowBuildTreesToolbar(); break;
00669     case 2: SelectSignTool();        break;
00670   }
00671 }
00672 
00673 /* --- Music button menu --- */
00674 
00675 static void ToolbarMusicClick(Window *w)
00676 {
00677   PopupMainToolbMenu(w, TBN_MUSICSOUND, STR_01D3_SOUND_MUSIC, 1);
00678 }
00679 
00680 static void MenuClickMusicWindow(int index)
00681 {
00682   ShowMusicWindow();
00683 }
00684 
00685 /* --- Newspaper button menu --- */
00686 
00687 static void ToolbarNewspaperClick(Window *w)
00688 {
00689   PopupMainToolbMenu(w, TBN_NEWSREPORT, STR_0200_LAST_MESSAGE_NEWS_REPORT, 3);
00690 }
00691 
00692 static void MenuClickNewspaper(int index)
00693 {
00694   switch (index) {
00695     case 0: ShowLastNewsMessage(); break;
00696     case 1: ShowMessageOptions();  break;
00697     case 2: ShowMessageHistory();  break;
00698   }
00699 }
00700 
00701 /* --- Help button menu --- */
00702 
00703 static void ToolbarHelpClick(Window *w)
00704 {
00705   PopupMainToolbMenu(w, TBN_HELP, STR_02D5_LAND_BLOCK_INFO, 6);
00706 }
00707 
00708 static void MenuClickSmallScreenshot()
00709 {
00710   SetScreenshotType(SC_VIEWPORT);
00711 }
00712 
00713 static void MenuClickWorldScreenshot()
00714 {
00715   SetScreenshotType(SC_WORLD);
00716 }
00717 
00718 static void MenuClickHelp(int index)
00719 {
00720   switch (index) {
00721     case 0: PlaceLandBlockInfo();       break;
00722     case 2: IConsoleSwitch();           break;
00723     case 3: MenuClickSmallScreenshot(); break;
00724     case 4: MenuClickWorldScreenshot(); break;
00725     case 5: ShowAboutWindow();          break;
00726   }
00727 }
00728 
00729 /* --- Switch toolbar button --- */
00730 
00731 static void ToolbarSwitchClick(Window *w)
00732 {
00733   if (_toolbar_mode != TB_LOWER) {
00734     _toolbar_mode = TB_LOWER;
00735   } else {
00736     _toolbar_mode = TB_UPPER;
00737   }
00738 
00739   SplitToolbar(w);
00740   w->HandleButtonClick(TBN_SWITCHBAR);
00741   SetWindowDirty(w);
00742   SndPlayFx(SND_15_BEEP);
00743 }
00744 
00745 /* --- Scenario editor specific handlers. */
00746 
00747 static void ToolbarScenDateBackward(Window *w)
00748 {
00749   /* don't allow too fast scrolling */
00750   if ((w->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
00751     w->HandleButtonClick(TBSE_DATEBACKWARD);
00752     w->SetDirty();
00753 
00754     _settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year - 1, MIN_YEAR, MAX_YEAR);
00755     SetDate(ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1));
00756   }
00757   _left_button_clicked = false;
00758 }
00759 
00760 static void ToolbarScenDateForward(Window *w)
00761 {
00762   /* don't allow too fast scrolling */
00763   if ((w->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
00764     w->HandleButtonClick(TBSE_DATEFORWARD);
00765     w->SetDirty();
00766 
00767     _settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + 1, MIN_YEAR, MAX_YEAR);
00768     SetDate(ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1));
00769   }
00770   _left_button_clicked = false;
00771 }
00772 
00773 static void ToolbarScenGenLand(Window *w)
00774 {
00775   w->HandleButtonClick(TBSE_LANDGENERATE);
00776   SndPlayFx(SND_15_BEEP);
00777 
00778   ShowEditorTerraformToolbar();
00779 }
00780 
00781 
00782 static void ToolbarScenGenTown(Window *w)
00783 {
00784   w->HandleButtonClick(TBSE_TOWNGENERATE);
00785   SndPlayFx(SND_15_BEEP);
00786   ShowBuildTownWindow();
00787 }
00788 
00789 static void ToolbarScenGenIndustry(Window *w)
00790 {
00791   w->HandleButtonClick(TBSE_INDUSTRYGENERATE);
00792   SndPlayFx(SND_15_BEEP);
00793   ShowBuildIndustryWindow();
00794 }
00795 
00796 static void ToolbarScenBuildRoad(Window *w)
00797 {
00798   w->HandleButtonClick(TBSE_BUILDROAD);
00799   SndPlayFx(SND_15_BEEP);
00800   ShowBuildRoadScenToolbar();
00801 }
00802 
00803 static void ToolbarScenBuildDocks(Window *w)
00804 {
00805   w->HandleButtonClick(TBSE_BUILDDOCKS);
00806   SndPlayFx(SND_15_BEEP);
00807   ShowBuildDocksScenToolbar();
00808 }
00809 
00810 static void ToolbarScenPlantTrees(Window *w)
00811 {
00812   w->HandleButtonClick(TBSE_PLANTTREES);
00813   SndPlayFx(SND_15_BEEP);
00814   ShowBuildTreesToolbar();
00815 }
00816 
00817 static void ToolbarScenPlaceSign(Window *w)
00818 {
00819   w->HandleButtonClick(TBSE_PLACESIGNS);
00820   SndPlayFx(SND_15_BEEP);
00821   SelectSignTool();
00822 }
00823 
00824 static void ToolbarBtn_NULL(Window *w)
00825 {
00826 }
00827 
00828 /* --- Resizing the toolbar */
00829 
00830 static void ResizeToolbar(Window *w)
00831 {
00832   /* There are 27 buttons plus some spacings if the space allows it */
00833   uint button_width;
00834   uint spacing;
00835   uint widgetcount = w->widget_count - 1;
00836 
00837   if (w->width >= (int)widgetcount * TBP_BUTTONWIDTH) {
00838     button_width = TBP_BUTTONWIDTH;
00839     spacing = w->width - (widgetcount * button_width);
00840   } else {
00841     button_width = w->width / widgetcount;
00842     spacing = 0;
00843   }
00844 
00845   static const uint extra_spacing_at[] = { 4, 8, 13, 17, 19, 24, 0 };
00846   uint i = 0;
00847   for (uint x = 0, j = 0; i < widgetcount; i++) {
00848     if (extra_spacing_at[j] == i) {
00849       j++;
00850       uint add = spacing / (lengthof(extra_spacing_at) - j);
00851       spacing -= add;
00852       x += add;
00853     }
00854 
00855     w->widget[i].type = WWT_IMGBTN;
00856     w->widget[i].left = x;
00857     x += (spacing != 0) ? button_width : (w->width - x) / (widgetcount - i);
00858     w->widget[i].right = x - 1;
00859   }
00860 
00861   w->widget[i].type = WWT_EMPTY; // i now points to the last item
00862   _toolbar_mode = TB_NORMAL;
00863 }
00864 
00865 /* --- Split the toolbar */
00866 
00867 static void SplitToolbar(Window *w)
00868 {
00869   static const byte arrange14[] = {
00870     0,  1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 27,
00871     2,  3,  4,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 27,
00872   };
00873   static const byte arrange15[] = {
00874     0,  1,  4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
00875     0,  2,  4,  3,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 27,
00876   };
00877   static const byte arrange16[] = {
00878     0,  1,  2,  4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
00879     0,  1,  3,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 17, 18, 27,
00880   };
00881   static const byte arrange17[] = {
00882     0,  1,  2,  4,  6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
00883     0,  1,  3,  4,  6,  5,  7,  8,  9, 10, 12, 24, 25, 26, 17, 18, 27,
00884   };
00885   static const byte arrange18[] = {
00886     0,  1,  2,  4,  5,  6,  7,  8,  9, 12, 19, 20, 21, 22, 23, 17, 18, 27,
00887     0,  1,  3,  4,  5,  6,  7, 10, 13, 14, 15, 16, 24, 25, 26, 17, 18, 27,
00888   };
00889   static const byte arrange19[] = {
00890     0,  1,  2,  4,  5,  6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 27,
00891     0,  1,  3,  4,  7,  8,  9, 10, 12, 25, 19, 20, 21, 22, 23, 26, 17, 18, 27,
00892   };
00893 
00894   static const byte *arrangements[] = { arrange14, arrange15, arrange16, arrange17, arrange18, arrange19 };
00895 
00896   uint max_icons = max(TBP_TOOLBAR_MINBUTTON, (ToolBarProperties)((w->width + TBP_BUTTONWIDTH / 2) / TBP_BUTTONWIDTH));
00897 
00898   assert(max_icons >= TBP_TOOLBAR_MINBUTTON && max_icons <= TBP_NORMAL_MAXBUTTON);
00899 
00900   /* first hide all icons */
00901   for (uint i = 0; i < w->widget_count - 1; i++) {
00902     w->widget[i].type = WWT_EMPTY;
00903   }
00904 
00905   /* now activate them all on their proper positions */
00906   for (uint i = 0, x = 0, n = max_icons - TBP_TOOLBAR_MINBUTTON; i < max_icons; i++) {
00907     uint icon = arrangements[n][i + ((_toolbar_mode == TB_LOWER) ? max_icons : 0)];
00908     w->widget[icon].type = WWT_IMGBTN;
00909     w->widget[icon].left = x;
00910     x += (w->width - x) / (max_icons - i);
00911     w->widget[icon].right = x - 1;
00912   }
00913 }
00914 
00915 typedef void MenuClickedProc(int index);
00916 
00917 static MenuClickedProc * const _menu_clicked_procs[] = {
00918   NULL,                 /* 0 */
00919   NULL,                 /* 1 */
00920   MenuClickSettings,    /* 2 */
00921   MenuClickSaveLoad,    /* 3 */
00922   MenuClickMap,         /* 4 */
00923   MenuClickTown,        /* 5 */
00924   MenuClickSubsidies,   /* 6 */
00925   MenuClickStations,    /* 7 */
00926   MenuClickFinances,    /* 8 */
00927   MenuClickCompany,     /* 9 */
00928   MenuClickGraphs,      /* 10 */
00929   MenuClickLeague,      /* 11 */
00930   MenuClickIndustry,    /* 12 */
00931   MenuClickShowTrains,  /* 13 */
00932   MenuClickShowRoad,    /* 14 */
00933   MenuClickShowShips,   /* 15 */
00934   MenuClickShowAir,     /* 16 */
00935   MenuClickMap,         /* 17 */
00936   NULL,                 /* 18 */
00937   MenuClickBuildRail,   /* 19 */
00938   MenuClickBuildRoad,   /* 20 */
00939   MenuClickBuildWater,  /* 21 */
00940   MenuClickBuildAir,    /* 22 */
00941   MenuClickForest,      /* 23 */
00942   MenuClickMusicWindow, /* 24 */
00943   MenuClickNewspaper,   /* 25 */
00944   MenuClickHelp,        /* 26 */
00945 };
00946 
00947 /* --- Toolbar handling for the 'normal' case */
00948 
00949 typedef void ToolbarButtonProc(Window *w);
00950 
00951 static ToolbarButtonProc * const _toolbar_button_procs[] = {
00952   ToolbarPauseClick,
00953   ToolbarFastForwardClick,
00954   ToolbarOptionsClick,
00955   ToolbarSaveClick,
00956   ToolbarMapClick,
00957   ToolbarTownClick,
00958   ToolbarSubsidiesClick,
00959   ToolbarStationsClick,
00960   ToolbarFinancesClick,
00961   ToolbarCompaniesClick,
00962   ToolbarGraphsClick,
00963   ToolbarLeagueClick,
00964   ToolbarIndustryClick,
00965   ToolbarTrainClick,
00966   ToolbarRoadClick,
00967   ToolbarShipClick,
00968   ToolbarAirClick,
00969   ToolbarZoomInClick,
00970   ToolbarZoomOutClick,
00971   ToolbarBuildRailClick,
00972   ToolbarBuildRoadClick,
00973   ToolbarBuildWaterClick,
00974   ToolbarBuildAirClick,
00975   ToolbarForestClick,
00976   ToolbarMusicClick,
00977   ToolbarNewspaperClick,
00978   ToolbarHelpClick,
00979   ToolbarSwitchClick,
00980 };
00981 
00982 struct MainToolbarWindow : Window {
00983   MainToolbarWindow(const WindowDesc *desc) : Window(desc)
00984   {
00985     this->SetWidgetDisabledState(TBN_PAUSE, _networking && !_network_server); // if not server, disable pause button
00986     this->SetWidgetDisabledState(TBN_FASTFORWARD, _networking); // if networking, disable fast-forward button
00987 
00988     CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
00989 
00990     this->FindWindowPlacementAndResize(desc);
00991     PositionMainToolbar(this);
00992     DoZoomInOutWindow(ZOOM_NONE, this);
00993   }
00994 
00995   virtual void OnPaint()
00996   {
00997     /* Draw brown-red toolbar bg. */
00998     GfxFillRect(0, 0, this->width - 1, this->height - 1, 0xB2);
00999     GfxFillRect(0, 0, this->width - 1, this->height - 1, 0xB4, FILLRECT_CHECKER);
01000 
01001     /* If spectator, disable all construction buttons
01002     * ie : Build road, rail, ships, airports and landscaping
01003     * Since enabled state is the default, just disable when needed */
01004     this->SetWidgetsDisabledState(_current_company == COMPANY_SPECTATOR, TBN_RAILS, TBN_ROADS, TBN_WATER, TBN_AIR, TBN_LANDSCAPE, WIDGET_LIST_END);
01005     /* disable company list drop downs, if there are no companies */
01006     this->SetWidgetsDisabledState(ActiveCompanyCount() == TBN_PAUSE, TBN_STATIONS, TBN_FINANCES, TBN_TRAINS, TBN_ROADVEHS, TBN_SHIPS, TBN_AIRCRAFTS, WIDGET_LIST_END);
01007 
01008     this->SetWidgetDisabledState(TBN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN));
01009     this->SetWidgetDisabledState(TBN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT));
01010 
01011     this->DrawWidgets();
01012   }
01013 
01014   virtual void OnClick(Point pt, int widget)
01015   {
01016     if (_game_mode != GM_MENU && !this->IsWidgetDisabled(widget)) _toolbar_button_procs[widget](this);
01017   }
01018 
01019   virtual void OnDropdownSelect(int widget, int index)
01020   {
01021     _menu_clicked_procs[widget](index);
01022   }
01023 
01024   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
01025   {
01026     switch (keycode) {
01027       case WKC_F1: case WKC_PAUSE: ToolbarPauseClick(this); break;
01028       case WKC_F2: ShowGameOptions(); break;
01029       case WKC_F3: MenuClickSaveLoad(); break;
01030       case WKC_F4: ShowSmallMap(); break;
01031       case WKC_F5: ShowTownDirectory(); break;
01032       case WKC_F6: ShowSubsidiesList(); break;
01033       case WKC_F7: ShowCompanyStations(_local_company); break;
01034       case WKC_F8: ShowCompanyFinances(_local_company); break;
01035       case WKC_F9: ShowCompany(_local_company); break;
01036       case WKC_F10: ShowOperatingProfitGraph(); break;
01037       case WKC_F11: ShowCompanyLeagueTable(); break;
01038       case WKC_F12: ShowBuildIndustryWindow(); break;
01039       case WKC_SHIFT | WKC_F1: ShowVehicleListWindow(_local_company, VEH_TRAIN); break;
01040       case WKC_SHIFT | WKC_F2: ShowVehicleListWindow(_local_company, VEH_ROAD); break;
01041       case WKC_SHIFT | WKC_F3: ShowVehicleListWindow(_local_company, VEH_SHIP); break;
01042       case WKC_SHIFT | WKC_F4: ShowVehicleListWindow(_local_company, VEH_AIRCRAFT); break;
01043       case WKC_NUM_PLUS: // Fall through
01044       case WKC_EQUALS: // Fall through
01045       case WKC_SHIFT | WKC_EQUALS: // Fall through
01046       case WKC_SHIFT | WKC_F5: ToolbarZoomInClick(this); break;
01047       case WKC_NUM_MINUS: // Fall through
01048       case WKC_MINUS: // Fall through
01049       case WKC_SHIFT | WKC_MINUS: // Fall through
01050       case WKC_SHIFT | WKC_F6: ToolbarZoomOutClick(this); break;
01051       case WKC_SHIFT | WKC_F7: if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype, -1); break;
01052       case WKC_SHIFT | WKC_F8: ShowBuildRoadToolbar(_last_built_roadtype); break;
01053       case WKC_SHIFT | WKC_F9: ShowBuildDocksToolbar(); break;
01054       case WKC_SHIFT | WKC_F10: if (CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) ShowBuildAirToolbar(); break;
01055       case WKC_SHIFT | WKC_F11: ShowBuildTreesToolbar(); break;
01056       case WKC_SHIFT | WKC_F12: ShowMusicWindow(); break;
01057       case WKC_CTRL  | 'S': MenuClickSmallScreenshot(); break;
01058       case WKC_CTRL  | 'G': MenuClickWorldScreenshot(); break;
01059       case WKC_CTRL | WKC_ALT | 'C': if (!_networking) ShowCheatWindow(); break;
01060       case 'A': if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype, 4); break; // Invoke Autorail
01061       case 'L': ShowTerraformToolbar(); break;
01062       case 'M': ShowSmallMap(); break;
01063       case 'V': ShowExtraViewPortWindow(); break;
01064       default: return ES_NOT_HANDLED;
01065     }
01066     return ES_HANDLED;