# toolbar_gui.cpp

Go to the documentation of this file.

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