# toolbar_gui.cpp

Go to the documentation of this file.

    00001 /* $Id: toolbar_gui.cpp 18546 2009-12-19 19:21:37Z rubidium $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    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     /* It's possible the company is deleted while the dropdown is open */
    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     /* Add the client list button for the companies menu */
    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 /* ENABLE_NETWORK */
    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 /* --- Pausing --- */
    00259
    00260 static void ToolbarPauseClick(Window *w)
    00261 {
    00262   if (_networking && !_network_server) return; // only server can pause the game
    00263
    00264   if (DoCommandP(0, PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED, CMD_PAUSE)) SndPlayFx(SND_15_BEEP);
    00265 }
    00266
    00267 /* --- Fast forwarding --- */
    00268
    00269 static void ToolbarFastForwardClick(Window *w)
    00270 {
    00271   _fast_forward ^= true;
    00272   SndPlayFx(SND_15_BEEP);
    00273 }
    00274
    00275 /* --- Options button menu --- */
    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 /* --- Saving/loading button menu --- */
    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 /* --- Map button menu --- */
    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 /* --- Town button menu --- */
    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: // setting could be changed when the dropdown was open
    00428       if (_settings_game.economy.found_town != TF_FORBIDDEN) ShowFoundTownWindow();
    00429       break;
    00430   }
    00431 }
    00432
    00433 /* --- Subidies button menu --- */
    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 /* --- Stations button menu --- */
    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 /* --- Finances button menu --- */
    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 /* --- Company's button menu --- */
    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 /* ENABLE_NETWORK */
    00504   ShowCompany((CompanyID)index);
    00505 }
    00506
    00507 /* --- Graphs button menu --- */
    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     /* functions for combined graphs/league button */
    00524     case 6: ShowCompanyLeagueTable();      break;
    00525     case 7: ShowPerformanceRatingDetail(); break;
    00526   }
    00527 }
    00528
    00529 /* --- League button menu --- */
    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 /* --- Industries button menu --- */
    00545
    00546 static void ToolbarIndustryClick(Window *w)
    00547 {
    00548   /* Disable build-industry menu if we are a spectator */
    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 /* --- Trains button menu + 1 helper function for all vehicles. --- */
    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 /* --- Road vehicle button menu --- */
    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 /* --- Ship button menu --- */
    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 /* --- Aircraft button menu --- */
    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 /* --- Zoom in button --- */
    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 /* --- Zoom out button --- */
    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 /* --- Rail button menu --- */
    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     /* Skip rail type if it has no label */
    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 /* --- Road button menu --- */
    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     /* The standard road button is *always* available */
    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 /* --- Water button menu --- */
    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 /* --- Airport button menu --- */
    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 /* --- Forest button menu --- */
    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 /* --- Music button menu --- */
    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 /* --- Newspaper button menu --- */
    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 /* --- Help button menu --- */
    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 /* --- Switch toolbar button --- */
    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 /* --- Scenario editor specific handlers. */
    00795
    00796 static void ToolbarScenDateBackward(Window *w)
    00797 {
    00798   /* don't allow too fast scrolling */
    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   /* don't allow too fast scrolling */
    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,                 // 0
    00881   NULL,                 // 1
    00882   MenuClickSettings,    // 2
    00883   MenuClickSaveLoad,    // 3
    00884   MenuClickMap,         // 4
    00885   MenuClickTown,        // 5
    00886   MenuClickSubsidies,   // 6
    00887   MenuClickStations,    // 7
    00888   MenuClickFinances,    // 8
    00889   MenuClickCompany,     // 9
    00890   MenuClickGraphs,      // 10
    00891   MenuClickLeague,      // 11
    00892   MenuClickIndustry,    // 12
    00893   MenuClickShowTrains,  // 13
    00894   MenuClickShowRoad,    // 14
    00895   MenuClickShowShips,   // 15
    00896   MenuClickShowAir,     // 16
    00897   MenuClickMap,         // 17
    00898   NULL,                 // 18
    00899   MenuClickBuildRail,   // 19
    00900   MenuClickBuildRoad,   // 20
    00901   MenuClickBuildWater,  // 21
    00902   MenuClickBuildAir,    // 22
    00903   MenuClickForest,      // 23
    00904   MenuClickMusicWindow, // 24
    00905   MenuClickNewspaper,   // 25
    00906   MenuClickHelp,        // 26
    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; // Biggest child
    00933     this->smallest_y = 0; // Biggest child
    00934     this->fill_x = 1;
    00935     this->fill_y = 0;
    00936     this->resize_x = 1; // We only resize in this direction
    00937     this->resize_y = 0; // We never resize in this direction
    00938     this->spacers = 0;
    00939
    00940     /* First initialise some variables... */
    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     /* ... then in a second pass make sure the 'current' heights are set. Won't change ever. */
    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     /* Figure out what are the visible buttons */
    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     /* Create us ourselves a quick lookup table */
    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     /* Now assign the widgets to their rightful place */
    00985     uint position = 0; // Place to put next child relative to origin of the container.
    00986     uint spacer_space = max(0, (int)given_width - (int)(button_count * this->smallest_x)); // Remaining spacing for 'spacer' widgets
    00987     uint button_space = given_width - spacer_space; // Remaining spacing for the buttons
    00988     uint spacer_i = 0;
    00989     uint button_i = 0;
    00990
    00991     /* Index into the arrangement indices. The macro lastof cannot be used here! */
    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       /* If we have to give space to the spacers, do that */
    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       /* Buttons can be scaled, the others not. */
    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   /* virtual */ void Draw(const Window *w)
    01024   {
    01025     /* Draw brown-red toolbar bg. */
    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   /* virtual */ 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   /* virtual */ 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     /* If at least BIGGEST_ARRANGEMENT fit, just spread all the buttons nicely */
    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     /* Introduce the split toolbar */
    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     /* Find the size of panel_widths */
    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   /* virtual */ 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     /* If we can place all buttons *and* the panels, show them. */
    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     /* Otherwise don't show the date panel and if we can't fit half the buttons and the panels anymore, split the toolbar in two */
    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     /* Split toolbar */
    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 /* --- Toolbar handling for the 'normal' case */
    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); // if not server, disable pause button
    01216     this->SetWidgetDisabledState(TBN_FASTFORWARD, _networking); // if networking, disable fast-forward button
    01217     PositionMainToolbar(this);
    01218     DoZoomInOutWindow(ZOOM_NONE, this);
    01219   }
    01220
    01221   virtual void OnPaint()
    01222   {
    01223     /* If spectator, disable all construction buttons
    01224      * ie : Build road, rail, ships, airports and landscaping
    01225      * Since enabled state is the default, just disable when needed */
    01226     this->SetWidgetsDisabledState(_local_company == COMPANY_SPECTATOR, TBN_RAILS, TBN_ROADS, TBN_WATER, TBN_AIR, TBN_LANDSCAPE, WIDGET_LIST_END);
    01227     /* disable company list drop downs, if there are no companies */
    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: // Fall through
    01266       case WKC_EQUALS: // Fall through
    01267       case WKC_SHIFT | WKC_EQUALS: // Fall through
    01268       case WKC_SHIFT | WKC_F5: ToolbarZoomInClick(this); break;
    01269       case WKC_NUM_MINUS: // Fall through
    01270       case WKC_MINUS: // Fall through
    01271       case WKC_SHIFT | WKC_MINUS: // Fall through
    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; // Invoke Autorail
    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     /* We do not want to automatically raise the pause, fast forward and
    01313      * switchbar buttons; they have to stay down when pressed etc. */
    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,           // TBN_PAUSE
    01333     SPR_IMG_FASTFORWARD,     // TBN_FASTFORWARD
    01334     SPR_IMG_SETTINGS,        // TBN_SETTINGS
    01335     SPR_IMG_SAVE,            // TBN_SAVEGAME
    01336     SPR_IMG_SMALLMAP,        // TBN_SMALLMAP
    01337     SPR_IMG_TOWN,            // TBN_TOWNDIRECTORY
    01338     SPR_IMG_SUBSIDIES,       // TBN_SUBSIDIES
    01339     SPR_IMG_COMPANY_LIST,    // TBN_STATIONS
    01340     SPR_IMG_COMPANY_FINANCE, // TBN_FINANCES
    01341     SPR_IMG_COMPANY_GENERAL, // TBN_COMPANIES
    01342     SPR_IMG_GRAPHS,          // TBN_GRAPHICS
    01343     SPR_IMG_COMPANY_LEAGUE,  // TBN_LEAGUE
    01344     SPR_IMG_INDUSTRY,        // TBN_INDUSTRIES
    01345     SPR_IMG_TRAINLIST,       // TBN_TRAINS
    01346     SPR_IMG_TRUCKLIST,       // TBN_ROADVEHS
    01347     SPR_IMG_SHIPLIST,        // TBN_SHIPS
    01348     SPR_IMG_AIRPLANESLIST,   // TBN_AIRCRAFTS
    01349     SPR_IMG_ZOOMIN,          // TBN_ZOOMIN
    01350     SPR_IMG_ZOOMOUT,         // TBN_ZOOMOUT
    01351     SPR_IMG_BUILDRAIL,       // TBN_RAILS
    01352     SPR_IMG_BUILDROAD,       // TBN_ROADS
    01353     SPR_IMG_BUILDWATER,      // TBN_WATER
    01354     SPR_IMG_BUILDAIR,        // TBN_AIR
    01355     SPR_IMG_LANDSCAPING,     // TBN_LANDSCAPE
    01356     SPR_IMG_MUSIC,           // TBN_MUSICSOUND
    01357     SPR_IMG_MESSAGES,        // TBN_NEWSREPORT
    01358     SPR_IMG_QUERY,           // TBN_HELP
    01359     SPR_IMG_SWITCH_TOOLBAR,  // TBN_SWITCHBAR
    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 /* --- Toolbar handling for the scenario editor */
    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     /* The map button is in a different location on the scenario
    01482      * editor toolbar, so we need to adjust for it. */
    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       /* those following are all fall through */
    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       /* those following are all fall through */
    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 /* --- Allocating the toolbar --- */
    01609
    01610 void AllocateToolbar()
    01611 {
    01612   /* Clean old GUI values; railtype is (re)set by rail_gui.cpp */
    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 }