# toolbar_gui.cpp

Go to the documentation of this file.

    00001 /* $Id: toolbar_gui.cpp 22684 2011-07-24 14:34:38Z 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 "vehicle_gui.h"
    00019 #include "rail_gui.h"
    00020 #include "road_gui.h"
    00021 #include "date_func.h"
    00022 #include "vehicle_func.h"
    00023 #include "sound_func.h"
    00024 #include "terraform_gui.h"
    00025 #include "transparency.h"
    00026 #include "strings_func.h"
    00027 #include "company_func.h"
    00028 #include "company_gui.h"
    00029 #include "vehicle_base.h"
    00030 #include "cheat_func.h"
    00031 #include "transparency_gui.h"
    00032 #include "screenshot.h"
    00033 #include "signs_func.h"
    00034 #include "fios.h"
    00035 #include "console_gui.h"
    00036 #include "news_gui.h"
    00037 #include "ai/ai_gui.hpp"
    00038 #include "tilehighlight_func.h"
    00039 #include "smallmap_gui.h"
    00040 #include "graph_gui.h"
    00041 #include "textbuf_gui.h"
    00042 #include "newgrf_debug.h"
    00043 #include "hotkeys.h"
    00044 #include "engine_base.h"
    00045
    00046 #include "network/network.h"
    00047 #include "network/network_gui.h"
    00048 #include "network/network_func.h"
    00049
    00050 #include "table/strings.h"
    00051 #include "table/sprites.h"
    00052
    00053 RailType _last_built_railtype;
    00054 RoadType _last_built_roadtype;
    00055
    00056 enum ToolbarMode {
    00057   TB_NORMAL,
    00058   TB_UPPER,
    00059   TB_LOWER
    00060 };
    00061
    00063 enum CallBackFunction {
    00064   CBF_NONE,
    00065   CBF_PLACE_SIGN,
    00066   CBF_PLACE_LANDINFO,
    00067 };
    00068
    00069 enum ToolbarNormalWidgets {
    00070   TBN_PAUSE         = 0,
    00071   TBN_FASTFORWARD,
    00072   TBN_SETTINGS,
    00073   TBN_SAVEGAME,
    00074   TBN_SMALLMAP,
    00075   TBN_TOWNDIRECTORY,
    00076   TBN_SUBSIDIES,
    00077   TBN_STATIONS,
    00078   TBN_FINANCES,
    00079   TBN_COMPANIES,
    00080   TBN_GRAPHICS,
    00081   TBN_LEAGUE,
    00082   TBN_INDUSTRIES,
    00083   TBN_VEHICLESTART,
    00084   TBN_TRAINS        = TBN_VEHICLESTART,
    00085   TBN_ROADVEHS,
    00086   TBN_SHIPS,
    00087   TBN_AIRCRAFTS,
    00088   TBN_ZOOMIN,
    00089   TBN_ZOOMOUT,
    00090   TBN_RAILS,
    00091   TBN_ROADS,
    00092   TBN_WATER,
    00093   TBN_AIR,
    00094   TBN_LANDSCAPE,
    00095   TBN_MUSICSOUND,
    00096   TBN_NEWSREPORT,
    00097   TBN_HELP,
    00098   TBN_SWITCHBAR,
    00099   TBN_END
    00100 };
    00101
    00102 enum ToolbarScenEditorWidgets {
    00103   TBSE_PAUSE        = 0,
    00104   TBSE_FASTFORWARD,
    00105   TBSE_SETTINGS,
    00106   TBSE_SAVESCENARIO,
    00107   TBSE_SPACERPANEL,
    00108   TBSE_DATEPANEL,
    00109   TBSE_DATEBACKWARD,
    00110   TBSE_DATEFORWARD,
    00111   TBSE_SMALLMAP,
    00112   TBSE_ZOOMIN,
    00113   TBSE_ZOOMOUT,
    00114   TBSE_LANDGENERATE,
    00115   TBSE_TOWNGENERATE,
    00116   TBSE_INDUSTRYGENERATE,
    00117   TBSE_BUILDROAD,
    00118   TBSE_BUILDDOCKS,
    00119   TBSE_PLANTTREES,
    00120   TBSE_PLACESIGNS,
    00121   TBSE_DATEPANEL_CONTAINER,
    00122 };
    00123
    00127 class DropDownListCheckedItem : public DropDownListStringItem {
    00128   uint checkmark_width;
    00129 public:
    00130   bool checked;
    00131
    00132   DropDownListCheckedItem(StringID string, int result, bool masked, bool checked) : DropDownListStringItem(string, result, masked), checked(checked)
    00133   {
    00134     this->checkmark_width = GetStringBoundingBox(STR_JUST_CHECKMARK).width + 3;
    00135   }
    00136
    00137   virtual ~DropDownListCheckedItem() {}
    00138
    00139   uint Width() const
    00140   {
    00141     return DropDownListStringItem::Width() + this->checkmark_width;
    00142   }
    00143
    00144   void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
    00145   {
    00146     bool rtl = _current_text_dir == TD_RTL;
    00147     if (this->checked) {
    00148       DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, STR_JUST_CHECKMARK, sel ? TC_WHITE : TC_BLACK);
    00149     }
    00150     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);
    00151   }
    00152 };
    00153
    00157 class DropDownListCompanyItem : public DropDownListItem {
    00158   uint icon_width;
    00159 public:
    00160   bool greyed;
    00161
    00162   DropDownListCompanyItem(int result, bool masked, bool greyed) : DropDownListItem(result, masked), greyed(greyed)
    00163   {
    00164     this->icon_width = GetSpriteSize(SPR_COMPANY_ICON).width;
    00165   }
    00166
    00167   virtual ~DropDownListCompanyItem() {}
    00168
    00169   bool Selectable() const
    00170   {
    00171     return true;
    00172   }
    00173
    00174   uint Width() const
    00175   {
    00176     CompanyID company = (CompanyID)this->result;
    00177     SetDParam(0, company);
    00178     SetDParam(1, company);
    00179     return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_width + 3;
    00180   }
    00181
    00182   void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
    00183   {
    00184     CompanyID company = (CompanyID)this->result;
    00185     bool rtl = _current_text_dir == TD_RTL;
    00186
    00187     /* It's possible the company is deleted while the dropdown is open */
    00188     if (!Company::IsValidID(company)) return;
    00189
    00190     DrawCompanyIcon(company, rtl ? right - this->icon_width - WD_FRAMERECT_RIGHT : left + WD_FRAMERECT_LEFT, top + 1 + (FONT_HEIGHT_NORMAL - 10) / 2);
    00191
    00192     SetDParam(0, company);
    00193     SetDParam(1, company);
    00194     TextColour col;
    00195     if (this->greyed) {
    00196       col = TC_GREY;
    00197     } else {
    00198       col = sel ? TC_WHITE : TC_BLACK;
    00199     }
    00200     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);
    00201   }
    00202 };
    00203
    00207 static void PopupMainToolbMenu(Window *w, int widget, StringID string, int count)
    00208 {
    00209   DropDownList *list = new DropDownList();
    00210   for (int i = 0; i < count; i++) {
    00211     list->push_back(new DropDownListStringItem(string + i, i, false));
    00212   }
    00213   ShowDropDownList(w, list, 0, widget, 140, true, true);
    00214   SndPlayFx(SND_15_BEEP);
    00215 }
    00216
    00218 static const int CTMN_CLIENT_LIST = -1;
    00219 static const int CTMN_NEW_COMPANY = -2;
    00220 static const int CTMN_SPECTATE    = -3;
    00221
    00225 static void PopupMainCompanyToolbMenu(Window *w, int widget, int grey = 0)
    00226 {
    00227   DropDownList *list = new DropDownList();
    00228
    00229 #ifdef ENABLE_NETWORK
    00230   if (widget == TBN_COMPANIES && _networking) {
    00231     /* Add the client list button for the companies menu */
    00232     list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, CTMN_CLIENT_LIST, false));
    00233
    00234     if (_local_company == COMPANY_SPECTATOR) {
    00235       list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_NEW_COMPANY, CTMN_NEW_COMPANY, NetworkMaxCompaniesReached()));
    00236     } else {
    00237       list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_SPECTATE, CTMN_SPECTATE, NetworkMaxSpectatorsReached()));
    00238     }
    00239   }
    00240 #endif /* ENABLE_NETWORK */
    00241
    00242   for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
    00243     if (!Company::IsValidID(c)) continue;
    00244     list->push_back(new DropDownListCompanyItem(c, false, HasBit(grey, c)));
    00245   }
    00246
    00247   ShowDropDownList(w, list, _local_company == COMPANY_SPECTATOR ? CTMN_CLIENT_LIST : (int)_local_company, widget, 240, true, true);
    00248   SndPlayFx(SND_15_BEEP);
    00249 }
    00250
    00251
    00252 static ToolbarMode _toolbar_mode;
    00253
    00254 static CallBackFunction SelectSignTool()
    00255 {
    00256   if (_cursor.sprite == SPR_CURSOR_SIGN) {
    00257     ResetObjectToPlace();
    00258     return CBF_NONE;
    00259   } else {
    00260     SetObjectToPlace(SPR_CURSOR_SIGN, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0);
    00261     return CBF_PLACE_SIGN;
    00262   }
    00263 }
    00264
    00265 /* --- Pausing --- */
    00266
    00267 static CallBackFunction ToolbarPauseClick(Window *w)
    00268 {
    00269   if (_networking && !_network_server) return CBF_NONE; // only server can pause the game
    00270
    00271   if (DoCommandP(0, PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED, CMD_PAUSE)) SndPlayFx(SND_15_BEEP);
    00272   return CBF_NONE;
    00273 }
    00274
    00275 /* --- Fast forwarding --- */
    00276
    00277 static CallBackFunction ToolbarFastForwardClick(Window *w)
    00278 {
    00279   _fast_forward ^= true;
    00280   SndPlayFx(SND_15_BEEP);
    00281   return CBF_NONE;
    00282 }
    00283
    00284 /* --- Options button menu --- */
    00285
    00286 enum OptionMenuEntries {
    00287   OME_GAMEOPTIONS,
    00288   OME_DIFFICULTIES,
    00289   OME_SETTINGS,
    00290   OME_AI_SETTINGS,
    00291   OME_NEWGRFSETTINGS,
    00292   OME_TRANSPARENCIES,
    00293   OME_SHOW_TOWNNAMES,
    00294   OME_SHOW_STATIONNAMES,
    00295   OME_SHOW_WAYPOINTNAMES,
    00296   OME_SHOW_SIGNS,
    00297   OME_FULL_ANIMATION,
    00298   OME_FULL_DETAILS,
    00299   OME_TRANSPARENTBUILDINGS,
    00300   OME_SHOW_STATIONSIGNS,
    00301 };
    00302
    00303 static CallBackFunction ToolbarOptionsClick(Window *w)
    00304 {
    00305   DropDownList *list = new DropDownList();
    00306   list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_GAME_OPTIONS,             OME_GAMEOPTIONS, false));
    00307   list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_DIFFICULTY_SETTINGS,      OME_DIFFICULTIES, false));
    00308   list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_CONFIG_SETTINGS,          OME_SETTINGS, false));
    00309   /* Changes to the per-AI settings don't get send from the server to the clients. Clients get
    00310    * the settings once they join but never update it. As such don't show the window at all
    00311    * to network clients. */
    00312   if (!_networking || _network_server) list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_AI_SETTINGS, OME_AI_SETTINGS, false));
    00313   list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_NEWGRF_SETTINGS,          OME_NEWGRFSETTINGS, false));
    00314   list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS,     OME_TRANSPARENCIES, false));
    00315   list->push_back(new DropDownListItem(-1, false));
    00316   list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED,    OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES)));
    00317   list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false, HasBit(_display_opt, DO_SHOW_STATION_NAMES)));
    00318   list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED,     OME_SHOW_WAYPOINTNAMES, false, HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES)));
    00319   list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_SIGNS_DISPLAYED,         OME_SHOW_SIGNS, false, HasBit(_display_opt, DO_SHOW_SIGNS)));
    00320   list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_ANIMATION,          OME_FULL_ANIMATION, false, HasBit(_display_opt, DO_FULL_ANIMATION)));
    00321   list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_DETAIL,             OME_FULL_DETAILS, false, HasBit(_display_opt, DO_FULL_DETAIL)));
    00322   list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS,   OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES)));
    00323   list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_SIGNS,       OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS)));
    00324
    00325   ShowDropDownList(w, list, 0, TBN_SETTINGS, 140, true, true);
    00326   SndPlayFx(SND_15_BEEP);
    00327   return CBF_NONE;
    00328 }
    00329
    00330 static CallBackFunction MenuClickSettings(int index)
    00331 {
    00332   switch (index) {
    00333     case OME_GAMEOPTIONS:          ShowGameOptions();                               return CBF_NONE;
    00334     case OME_DIFFICULTIES:         ShowGameDifficulty();                            return CBF_NONE;
    00335     case OME_SETTINGS:             ShowGameSettings();                              return CBF_NONE;
    00336     case OME_AI_SETTINGS:          ShowAIConfigWindow();                            return CBF_NONE;
    00337     case OME_NEWGRFSETTINGS:       ShowNewGRFSettings(!_networking && _settings_client.gui.UserIsAllowedToChangeNewGRFs(), true, true, &_grfconfig); return CBF_NONE;
    00338     case OME_TRANSPARENCIES:       ShowTransparencyToolbar();                       break;
    00339
    00340     case OME_SHOW_TOWNNAMES:       ToggleBit(_display_opt, DO_SHOW_TOWN_NAMES);     break;
    00341     case OME_SHOW_STATIONNAMES:    ToggleBit(_display_opt, DO_SHOW_STATION_NAMES);  break;
    00342     case OME_SHOW_WAYPOINTNAMES:   ToggleBit(_display_opt, DO_SHOW_WAYPOINT_NAMES); break;
    00343     case OME_SHOW_SIGNS:           ToggleBit(_display_opt, DO_SHOW_SIGNS);          break;
    00344     case OME_FULL_ANIMATION:       ToggleBit(_display_opt, DO_FULL_ANIMATION);      break;
    00345     case OME_FULL_DETAILS:         ToggleBit(_display_opt, DO_FULL_DETAIL);         break;
    00346     case OME_TRANSPARENTBUILDINGS: ToggleTransparency(TO_HOUSES);                   break;
    00347     case OME_SHOW_STATIONSIGNS:    ToggleTransparency(TO_SIGNS);                    break;
    00348   }
    00349   MarkWholeScreenDirty();
    00350   return CBF_NONE;
    00351 }
    00352
    00353 /* --- Saving/loading button menu --- */
    00354
    00355 enum SaveLoadEditorMenuEntries {
    00356   SLEME_SAVE_SCENARIO   = 0,
    00357   SLEME_LOAD_SCENARIO,
    00358   SLEME_LOAD_HEIGHTMAP,
    00359   SLEME_EXIT_TOINTRO,
    00360   SLEME_EXIT_GAME       = 5,
    00361   SLEME_MENUCOUNT,
    00362 };
    00363
    00364 enum SaveLoadNormalMenuEntries {
    00365   SLNME_SAVE_GAME   = 0,
    00366   SLNME_LOAD_GAME,
    00367   SLNME_EXIT_TOINTRO,
    00368   SLNME_EXIT_GAME,
    00369   SLNME_MENUCOUNT,
    00370 };
    00371
    00372 static CallBackFunction ToolbarSaveClick(Window *w)
    00373 {
    00374   PopupMainToolbMenu(w, TBN_SAVEGAME, STR_FILE_MENU_SAVE_GAME, SLNME_MENUCOUNT);
    00375   return CBF_NONE;
    00376 }
    00377
    00378 static CallBackFunction ToolbarScenSaveOrLoad(Window *w)
    00379 {
    00380   PopupMainToolbMenu(w, TBSE_SAVESCENARIO, STR_SCENEDIT_FILE_MENU_SAVE_SCENARIO, SLEME_MENUCOUNT);
    00381   return CBF_NONE;
    00382 }
    00383
    00384 static CallBackFunction MenuClickSaveLoad(int index = 0)
    00385 {
    00386   if (_game_mode == GM_EDITOR) {
    00387     switch (index) {
    00388       case SLEME_SAVE_SCENARIO:  ShowSaveLoadDialog(SLD_SAVE_SCENARIO);  break;
    00389       case SLEME_LOAD_SCENARIO:  ShowSaveLoadDialog(SLD_LOAD_SCENARIO);  break;
    00390       case SLEME_LOAD_HEIGHTMAP: ShowSaveLoadDialog(SLD_LOAD_HEIGHTMAP); break;
    00391       case SLEME_EXIT_TOINTRO:   AskExitToGameMenu();                    break;
    00392       case SLEME_EXIT_GAME:      HandleExitGameRequest();                break;
    00393     }
    00394   } else {
    00395     switch (index) {
    00396       case SLNME_SAVE_GAME:      ShowSaveLoadDialog(SLD_SAVE_GAME); break;
    00397       case SLNME_LOAD_GAME:      ShowSaveLoadDialog(SLD_LOAD_GAME); break;
    00398       case SLNME_EXIT_TOINTRO:   AskExitToGameMenu();               break;
    00399       case SLNME_EXIT_GAME:      HandleExitGameRequest();           break;
    00400     }
    00401   }
    00402   return CBF_NONE;
    00403 }
    00404
    00405 /* --- Map button menu --- */
    00406
    00407 enum MapMenuEntries {
    00408   MME_SHOW_SMALLMAP        = 0,
    00409   MME_SHOW_EXTRAVIEWPORTS,
    00410   MME_SHOW_SIGNLISTS,
    00411   MME_SHOW_TOWNDIRECTORY,
    00412   MME_MENUCOUNT_NORMAL     = 3,
    00413   MME_MENUCOUNT_EDITOR     = 4,
    00414 };
    00415
    00416 static CallBackFunction ToolbarMapClick(Window *w)
    00417 {
    00418   PopupMainToolbMenu(w, TBN_SMALLMAP, STR_MAP_MENU_MAP_OF_WORLD, MME_MENUCOUNT_NORMAL);
    00419   return CBF_NONE;
    00420 }
    00421
    00422 static CallBackFunction ToolbarScenMapTownDir(Window *w)
    00423 {
    00424   PopupMainToolbMenu(w, TBSE_SMALLMAP, STR_MAP_MENU_MAP_OF_WORLD, MME_MENUCOUNT_EDITOR);
    00425   return CBF_NONE;
    00426 }
    00427
    00428 static CallBackFunction MenuClickMap(int index)
    00429 {
    00430   switch (index) {
    00431     case MME_SHOW_SMALLMAP:       ShowSmallMap();            break;
    00432     case MME_SHOW_EXTRAVIEWPORTS: ShowExtraViewPortWindow(); break;
    00433     case MME_SHOW_SIGNLISTS:      ShowSignList();            break;
    00434     case MME_SHOW_TOWNDIRECTORY:  if (_game_mode == GM_EDITOR) ShowTownDirectory(); break;
    00435   }
    00436   return CBF_NONE;
    00437 }
    00438
    00439 /* --- Town button menu --- */
    00440
    00441 static CallBackFunction ToolbarTownClick(Window *w)
    00442 {
    00443   PopupMainToolbMenu(w, TBN_TOWNDIRECTORY, STR_TOWN_MENU_TOWN_DIRECTORY, (_settings_game.economy.found_town == TF_FORBIDDEN) ? 1 : 2);
    00444   return CBF_NONE;
    00445 }
    00446
    00447 static CallBackFunction MenuClickTown(int index)
    00448 {
    00449   switch (index) {
    00450     case 0: ShowTownDirectory(); break;
    00451     case 1: // setting could be changed when the dropdown was open
    00452       if (_settings_game.economy.found_town != TF_FORBIDDEN) ShowFoundTownWindow();
    00453       break;
    00454   }
    00455   return CBF_NONE;
    00456 }
    00457
    00458 /* --- Subidies button menu --- */
    00459
    00460 static CallBackFunction ToolbarSubsidiesClick(Window *w)
    00461 {
    00462   PopupMainToolbMenu(w, TBN_SUBSIDIES, STR_SUBSIDIES_MENU_SUBSIDIES, 1);
    00463   return CBF_NONE;
    00464 }
    00465
    00466 static CallBackFunction MenuClickSubsidies(int index)
    00467 {
    00468   ShowSubsidiesList();
    00469   return CBF_NONE;
    00470 }
    00471
    00472 /* --- Stations button menu --- */
    00473
    00474 static CallBackFunction ToolbarStationsClick(Window *w)
    00475 {
    00476   PopupMainCompanyToolbMenu(w, TBN_STATIONS);
    00477   return CBF_NONE;
    00478 }
    00479
    00480 static CallBackFunction MenuClickStations(int index)
    00481 {
    00482   ShowCompanyStations((CompanyID)index);
    00483   return CBF_NONE;
    00484 }
    00485
    00486 /* --- Finances button menu --- */
    00487
    00488 static CallBackFunction ToolbarFinancesClick(Window *w)
    00489 {
    00490   PopupMainCompanyToolbMenu(w, TBN_FINANCES);
    00491   return CBF_NONE;
    00492 }
    00493
    00494 static CallBackFunction MenuClickFinances(int index)
    00495 {
    00496   ShowCompanyFinances((CompanyID)index);
    00497   return CBF_NONE;
    00498 }
    00499
    00500 /* --- Company's button menu --- */
    00501
    00502 static CallBackFunction ToolbarCompaniesClick(Window *w)
    00503 {
    00504   PopupMainCompanyToolbMenu(w, TBN_COMPANIES);
    00505   return CBF_NONE;
    00506 }
    00507
    00508 static CallBackFunction MenuClickCompany(int index)
    00509 {
    00510 #ifdef ENABLE_NETWORK
    00511   if (_networking) {
    00512     switch (index) {
    00513       case CTMN_CLIENT_LIST:
    00514         ShowClientList();
    00515         return CBF_NONE;
    00516
    00517       case CTMN_NEW_COMPANY:
    00518         if (_network_server) {
    00519           DoCommandP(0, 0, _network_own_client_id, CMD_COMPANY_CTRL);
    00520         } else {
    00521           NetworkSendCommand(0, 0, 0, CMD_COMPANY_CTRL, NULL, NULL, _local_company);
    00522         }
    00523         return CBF_NONE;
    00524
    00525       case CTMN_SPECTATE:
    00526         if (_network_server) {
    00527           NetworkServerDoMove(CLIENT_ID_SERVER, COMPANY_SPECTATOR);
    00528           MarkWholeScreenDirty();
    00529         } else {
    00530           NetworkClientRequestMove(COMPANY_SPECTATOR);
    00531         }
    00532         return CBF_NONE;
    00533     }
    00534   }
    00535 #endif /* ENABLE_NETWORK */
    00536   ShowCompany((CompanyID)index);
    00537   return CBF_NONE;
    00538 }
    00539
    00540 /* --- Graphs button menu --- */
    00541
    00542 static CallBackFunction ToolbarGraphsClick(Window *w)
    00543 {
    00544   PopupMainToolbMenu(w, TBN_GRAPHICS, STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH, (_toolbar_mode == TB_NORMAL) ? 6 : 8);
    00545   return CBF_NONE;
    00546 }
    00547
    00548 static CallBackFunction MenuClickGraphs(int index)
    00549 {
    00550   switch (index) {
    00551     case 0: ShowOperatingProfitGraph();    break;
    00552     case 1: ShowIncomeGraph();             break;
    00553     case 2: ShowDeliveredCargoGraph();     break;
    00554     case 3: ShowPerformanceHistoryGraph(); break;
    00555     case 4: ShowCompanyValueGraph();       break;
    00556     case 5: ShowCargoPaymentRates();       break;
    00557     /* functions for combined graphs/league button */
    00558     case 6: ShowCompanyLeagueTable();      break;
    00559     case 7: ShowPerformanceRatingDetail(); break;
    00560   }
    00561   return CBF_NONE;
    00562 }
    00563
    00564 /* --- League button menu --- */
    00565
    00566 static CallBackFunction ToolbarLeagueClick(Window *w)
    00567 {
    00568   PopupMainToolbMenu(w, TBN_LEAGUE, STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE, 2);
    00569   return CBF_NONE;
    00570 }
    00571
    00572 static CallBackFunction MenuClickLeague(int index)
    00573 {
    00574   switch (index) {
    00575     case 0: ShowCompanyLeagueTable();      break;
    00576     case 1: ShowPerformanceRatingDetail(); break;
    00577   }
    00578   return CBF_NONE;
    00579 }
    00580
    00581 /* --- Industries button menu --- */
    00582
    00583 static CallBackFunction ToolbarIndustryClick(Window *w)
    00584 {
    00585   /* Disable build-industry menu if we are a spectator */
    00586   PopupMainToolbMenu(w, TBN_INDUSTRIES, STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY, (_local_company == COMPANY_SPECTATOR) ? 1 : 2);
    00587   return CBF_NONE;
    00588 }
    00589
    00590 static CallBackFunction MenuClickIndustry(int index)
    00591 {
    00592   switch (index) {
    00593     case 0: ShowIndustryDirectory();   break;
    00594     case 1: ShowBuildIndustryWindow(); break;
    00595   }
    00596   return CBF_NONE;
    00597 }
    00598
    00599 /* --- Trains button menu + 1 helper function for all vehicles. --- */
    00600
    00601 static void ToolbarVehicleClick(Window *w, VehicleType veh)
    00602 {
    00603   const Vehicle *v;
    00604   int dis = ~0;
    00605
    00606   FOR_ALL_VEHICLES(v) {
    00607     if (v->type == veh && v->IsPrimaryVehicle()) ClrBit(dis, v->owner);
    00608   }
    00609   PopupMainCompanyToolbMenu(w, TBN_VEHICLESTART + veh, dis);
    00610 }
    00611
    00612
    00613 static CallBackFunction ToolbarTrainClick(Window *w)
    00614 {
    00615   ToolbarVehicleClick(w, VEH_TRAIN);
    00616   return CBF_NONE;
    00617 }
    00618
    00619 static CallBackFunction MenuClickShowTrains(int index)
    00620 {
    00621   ShowVehicleListWindow((CompanyID)index, VEH_TRAIN);
    00622   return CBF_NONE;
    00623 }
    00624
    00625 /* --- Road vehicle button menu --- */
    00626
    00627 static CallBackFunction ToolbarRoadClick(Window *w)
    00628 {
    00629   ToolbarVehicleClick(w, VEH_ROAD);
    00630   return CBF_NONE;
    00631 }
    00632
    00633 static CallBackFunction MenuClickShowRoad(int index)
    00634 {
    00635   ShowVehicleListWindow((CompanyID)index, VEH_ROAD);
    00636   return CBF_NONE;
    00637 }
    00638
    00639 /* --- Ship button menu --- */
    00640
    00641 static CallBackFunction ToolbarShipClick(Window *w)
    00642 {
    00643   ToolbarVehicleClick(w, VEH_SHIP);
    00644   return CBF_NONE;
    00645 }
    00646
    00647 static CallBackFunction MenuClickShowShips(int index)
    00648 {
    00649   ShowVehicleListWindow((CompanyID)index, VEH_SHIP);
    00650   return CBF_NONE;
    00651 }
    00652
    00653 /* --- Aircraft button menu --- */
    00654
    00655 static CallBackFunction ToolbarAirClick(Window *w)
    00656 {
    00657   ToolbarVehicleClick(w, VEH_AIRCRAFT);
    00658   return CBF_NONE;
    00659 }
    00660
    00661 static CallBackFunction MenuClickShowAir(int index)
    00662 {
    00663   ShowVehicleListWindow((CompanyID)index, VEH_AIRCRAFT);
    00664   return CBF_NONE;
    00665 }
    00666
    00667 /* --- Zoom in button --- */
    00668
    00669 static CallBackFunction ToolbarZoomInClick(Window *w)
    00670 {
    00671   if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) {
    00672     w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)TBSE_ZOOMIN : (byte)TBN_ZOOMIN);
    00673     SndPlayFx(SND_15_BEEP);
    00674   }
    00675   return CBF_NONE;
    00676 }
    00677
    00678 /* --- Zoom out button --- */
    00679
    00680 static CallBackFunction ToolbarZoomOutClick(Window *w)
    00681 {
    00682   if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) {
    00683     w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)TBSE_ZOOMOUT : (byte)TBN_ZOOMOUT);
    00684     SndPlayFx(SND_15_BEEP);
    00685   }
    00686   return CBF_NONE;
    00687 }
    00688
    00689 /* --- Rail button menu --- */
    00690
    00691 static CallBackFunction ToolbarBuildRailClick(Window *w)
    00692 {
    00693   ShowDropDownList(w, GetRailTypeDropDownList(), _last_built_railtype, TBN_RAILS, 140, true, true);
    00694   SndPlayFx(SND_15_BEEP);
    00695   return CBF_NONE;
    00696 }
    00697
    00698 static CallBackFunction MenuClickBuildRail(int index)
    00699 {
    00700   _last_built_railtype = (RailType)index;
    00701   ShowBuildRailToolbar(_last_built_railtype);
    00702   return CBF_NONE;
    00703 }
    00704
    00705 /* --- Road button menu --- */
    00706
    00707 static CallBackFunction ToolbarBuildRoadClick(Window *w)
    00708 {
    00709   const Company *c = Company::Get(_local_company);
    00710   DropDownList *list = new DropDownList();
    00711
    00712   /* Road is always visible and available. */
    00713   list->push_back(new DropDownListStringItem(STR_ROAD_MENU_ROAD_CONSTRUCTION, ROADTYPE_ROAD, false));
    00714
    00715   /* Tram is only visible when there will be a tram, and available when that has been introduced. */
    00716   Engine *e;
    00717   FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
    00718     if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue;
    00719     if (!HasBit(e->info.misc_flags, EF_ROAD_TRAM)) continue;
    00720
    00721     list->push_back(new DropDownListStringItem(STR_ROAD_MENU_TRAM_CONSTRUCTION, ROADTYPE_TRAM, !HasBit(c->avail_roadtypes, ROADTYPE_TRAM)));
    00722     break;
    00723   }
    00724   ShowDropDownList(w, list, _last_built_roadtype, TBN_ROADS, 140, true, true);
    00725   SndPlayFx(SND_15_BEEP);
    00726   return CBF_NONE;
    00727 }
    00728
    00729 static CallBackFunction MenuClickBuildRoad(int index)
    00730 {
    00731   _last_built_roadtype = (RoadType)index;
    00732   ShowBuildRoadToolbar(_last_built_roadtype);
    00733   return CBF_NONE;
    00734 }
    00735
    00736 /* --- Water button menu --- */
    00737
    00738 static CallBackFunction ToolbarBuildWaterClick(Window *w)
    00739 {
    00740   PopupMainToolbMenu(w, TBN_WATER, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 1);
    00741   return CBF_NONE;
    00742 }
    00743
    00744 static CallBackFunction MenuClickBuildWater(int index)
    00745 {
    00746   ShowBuildDocksToolbar();
    00747   return CBF_NONE;
    00748 }
    00749
    00750 /* --- Airport button menu --- */
    00751
    00752 static CallBackFunction ToolbarBuildAirClick(Window *w)
    00753 {
    00754   PopupMainToolbMenu(w, TBN_AIR, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 1);
    00755   return CBF_NONE;
    00756 }
    00757
    00758 static CallBackFunction MenuClickBuildAir(int index)
    00759 {
    00760   ShowBuildAirToolbar();
    00761   return CBF_NONE;
    00762 }
    00763
    00764 /* --- Forest button menu --- */
    00765
    00766 static CallBackFunction ToolbarForestClick(Window *w)
    00767 {
    00768   PopupMainToolbMenu(w, TBN_LANDSCAPE, STR_LANDSCAPING_MENU_LANDSCAPING, 3);
    00769   return CBF_NONE;
    00770 }
    00771
    00772 static CallBackFunction MenuClickForest(int index)
    00773 {
    00774   switch (index) {
    00775     case 0: ShowTerraformToolbar();  break;
    00776     case 1: ShowBuildTreesToolbar(); break;
    00777     case 2: return SelectSignTool();
    00778   }
    00779   return CBF_NONE;
    00780 }
    00781
    00782 /* --- Music button menu --- */
    00783
    00784 static CallBackFunction ToolbarMusicClick(Window *w)
    00785 {
    00786   PopupMainToolbMenu(w, TBN_MUSICSOUND, STR_TOOLBAR_SOUND_MUSIC, 1);
    00787   return CBF_NONE;
    00788 }
    00789
    00790 static CallBackFunction MenuClickMusicWindow(int index)
    00791 {
    00792   ShowMusicWindow();
    00793   return CBF_NONE;
    00794 }
    00795
    00796 /* --- Newspaper button menu --- */
    00797
    00798 static CallBackFunction ToolbarNewspaperClick(Window *w)
    00799 {
    00800   PopupMainToolbMenu(w, TBN_NEWSREPORT, STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT, 3);
    00801   return CBF_NONE;
    00802 }
    00803
    00804 static CallBackFunction MenuClickNewspaper(int index)
    00805 {
    00806   switch (index) {
    00807     case 0: ShowLastNewsMessage(); break;
    00808     case 1: ShowMessageOptions();  break;
    00809     case 2: ShowMessageHistory();  break;
    00810   }
    00811   return CBF_NONE;
    00812 }
    00813
    00814 /* --- Help button menu --- */
    00815
    00816 static CallBackFunction PlaceLandBlockInfo()
    00817 {
    00818   if (_cursor.sprite == SPR_CURSOR_QUERY) {
    00819     ResetObjectToPlace();
    00820     return CBF_NONE;
    00821   } else {
    00822     SetObjectToPlace(SPR_CURSOR_QUERY, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0);
    00823     return CBF_PLACE_LANDINFO;
    00824   }
    00825 }
    00826
    00827 static CallBackFunction ToolbarHelpClick(Window *w)
    00828 {
    00829   PopupMainToolbMenu(w, TBN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 10 : 8);
    00830   return CBF_NONE;
    00831 }
    00832
    00833 static void MenuClickSmallScreenshot()
    00834 {
    00835   MakeScreenshot(SC_VIEWPORT, NULL);
    00836 }
    00837
    00838 static void MenuClickZoomedInScreenshot()
    00839 {
    00840   MakeScreenshot(SC_ZOOMEDIN, NULL);
    00841 }
    00842
    00843 static void MenuClickWorldScreenshot()
    00844 {
    00845   MakeScreenshot(SC_WORLD, NULL);
    00846 }
    00847
    00855 void ToggleBoundingBoxes()
    00856 {
    00857   extern bool _draw_bounding_boxes;
    00858   /* Always allow to toggle them off */
    00859   if (_settings_client.gui.newgrf_developer_tools || _draw_bounding_boxes) {
    00860     _draw_bounding_boxes = !_draw_bounding_boxes;
    00861     MarkWholeScreenDirty();
    00862   }
    00863 }
    00864
    00870 static CallBackFunction MenuClickHelp(int index)
    00871 {
    00872   switch (index) {
    00873     case 0: return PlaceLandBlockInfo();
    00874     case 2: IConsoleSwitch();              break;
    00875     case 3: ShowAIDebugWindow();           break;
    00876     case 4: MenuClickSmallScreenshot();    break;
    00877     case 5: MenuClickZoomedInScreenshot(); break;
    00878     case 6: MenuClickWorldScreenshot();    break;
    00879     case 7: ShowAboutWindow();             break;
    00880     case 8: ShowSpriteAlignerWindow();     break;
    00881     case 9: ToggleBoundingBoxes();         break;
    00882   }
    00883   return CBF_NONE;
    00884 }
    00885
    00886 /* --- Switch toolbar button --- */
    00887
    00888 static CallBackFunction ToolbarSwitchClick(Window *w)
    00889 {
    00890   if (_toolbar_mode != TB_LOWER) {
    00891     _toolbar_mode = TB_LOWER;
    00892   } else {
    00893     _toolbar_mode = TB_UPPER;
    00894   }
    00895
    00896   w->ReInit();
    00897   w->SetWidgetLoweredState(TBN_SWITCHBAR, _toolbar_mode == TB_LOWER);
    00898   SndPlayFx(SND_15_BEEP);
    00899   return CBF_NONE;
    00900 }
    00901
    00902 /* --- Scenario editor specific handlers. */
    00903
    00907 static CallBackFunction ToolbarScenDatePanel(Window *w)
    00908 {
    00909   SetDParam(0, _settings_game.game_creation.starting_year);
    00910   ShowQueryString(STR_JUST_INT, STR_MAPGEN_START_DATE_QUERY_CAPT, 8, 100, w, CS_NUMERAL, QSF_ENABLE_DEFAULT);
    00911   _left_button_clicked = false;
    00912   return CBF_NONE;
    00913 }
    00914
    00915 static CallBackFunction ToolbarScenDateBackward(Window *w)
    00916 {
    00917   /* don't allow too fast scrolling */
    00918   if ((w->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
    00919     w->HandleButtonClick(TBSE_DATEBACKWARD);
    00920     w->SetDirty();
    00921
    00922     _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year - 1, MIN_YEAR, MAX_YEAR);
    00923     SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
    00924   }
    00925   _left_button_clicked = false;
    00926   return CBF_NONE;
    00927 }
    00928
    00929 static CallBackFunction ToolbarScenDateForward(Window *w)
    00930 {
    00931   /* don't allow too fast scrolling */
    00932   if ((w->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
    00933     w->HandleButtonClick(TBSE_DATEFORWARD);
    00934     w->SetDirty();
    00935
    00936     _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year + 1, MIN_YEAR, MAX_YEAR);
    00937     SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
    00938   }
    00939   _left_button_clicked = false;
    00940   return CBF_NONE;
    00941 }
    00942
    00943 static CallBackFunction ToolbarScenGenLand(Window *w)
    00944 {
    00945   w->HandleButtonClick(TBSE_LANDGENERATE);
    00946   SndPlayFx(SND_15_BEEP);
    00947
    00948   ShowEditorTerraformToolbar();
    00949   return CBF_NONE;
    00950 }
    00951
    00952
    00953 static CallBackFunction ToolbarScenGenTown(Window *w)
    00954 {
    00955   w->HandleButtonClick(TBSE_TOWNGENERATE);
    00956   SndPlayFx(SND_15_BEEP);
    00957   ShowFoundTownWindow();
    00958   return CBF_NONE;
    00959 }
    00960
    00961 static CallBackFunction ToolbarScenGenIndustry(Window *w)
    00962 {
    00963   w->HandleButtonClick(TBSE_INDUSTRYGENERATE);
    00964   SndPlayFx(SND_15_BEEP);
    00965   ShowBuildIndustryWindow();
    00966   return CBF_NONE;
    00967 }
    00968
    00969 static CallBackFunction ToolbarScenBuildRoad(Window *w)
    00970 {
    00971   w->HandleButtonClick(TBSE_BUILDROAD);
    00972   SndPlayFx(SND_15_BEEP);
    00973   ShowBuildRoadScenToolbar();
    00974   return CBF_NONE;
    00975 }
    00976
    00977 static CallBackFunction ToolbarScenBuildDocks(Window *w)
    00978 {
    00979   w->HandleButtonClick(TBSE_BUILDDOCKS);
    00980   SndPlayFx(SND_15_BEEP);
    00981   ShowBuildDocksScenToolbar();
    00982   return CBF_NONE;
    00983 }
    00984
    00985 static CallBackFunction ToolbarScenPlantTrees(Window *w)
    00986 {
    00987   w->HandleButtonClick(TBSE_PLANTTREES);
    00988   SndPlayFx(SND_15_BEEP);
    00989   ShowBuildTreesToolbar();
    00990   return CBF_NONE;
    00991 }
    00992
    00993 static CallBackFunction ToolbarScenPlaceSign(Window *w)
    00994 {
    00995   w->HandleButtonClick(TBSE_PLACESIGNS);
    00996   SndPlayFx(SND_15_BEEP);
    00997   return SelectSignTool();
    00998 }
    00999
    01000 static CallBackFunction ToolbarBtn_NULL(Window *w)
    01001 {
    01002   return CBF_NONE;
    01003 }
    01004
    01005 typedef CallBackFunction MenuClickedProc(int index);
    01006
    01007 static MenuClickedProc * const _menu_clicked_procs[] = {
    01008   NULL,                 // 0
    01009   NULL,                 // 1
    01010   MenuClickSettings,    // 2
    01011   MenuClickSaveLoad,    // 3
    01012   MenuClickMap,         // 4
    01013   MenuClickTown,        // 5
    01014   MenuClickSubsidies,   // 6
    01015   MenuClickStations,    // 7
    01016   MenuClickFinances,    // 8
    01017   MenuClickCompany,     // 9
    01018   MenuClickGraphs,      // 10
    01019   MenuClickLeague,      // 11
    01020   MenuClickIndustry,    // 12
    01021   MenuClickShowTrains,  // 13
    01022   MenuClickShowRoad,    // 14
    01023   MenuClickShowShips,   // 15
    01024   MenuClickShowAir,     // 16
    01025   MenuClickMap,         // 17
    01026   NULL,                 // 18
    01027   MenuClickBuildRail,   // 19
    01028   MenuClickBuildRoad,   // 20
    01029   MenuClickBuildWater,  // 21
    01030   MenuClickBuildAir,    // 22
    01031   MenuClickForest,      // 23
    01032   MenuClickMusicWindow, // 24
    01033   MenuClickNewspaper,   // 25
    01034   MenuClickHelp,        // 26
    01035 };
    01036
    01037 int16 *_preferred_toolbar_size = NULL;
    01038
    01040 class NWidgetToolbarContainer : public NWidgetContainer {
    01041   bool visible[TBN_END];
    01042 protected:
    01043   uint spacers;
    01044
    01045 public:
    01046   NWidgetToolbarContainer() : NWidgetContainer(NWID_HORIZONTAL)
    01047   {
    01048   }
    01049
    01055   bool IsButton(WidgetType type) const
    01056   {
    01057     return type == WWT_IMGBTN || type == WWT_IMGBTN_2 || type == WWT_PUSHIMGBTN;
    01058   }
    01059
    01060   void SetupSmallestSize(Window *w, bool init_array)
    01061   {
    01062     this->smallest_x = 0; // Biggest child
    01063     this->smallest_y = 0; // Biggest child
    01064     this->fill_x = 1;
    01065     this->fill_y = 0;
    01066     this->resize_x = 1; // We only resize in this direction
    01067     this->resize_y = 0; // We never resize in this direction
    01068     this->spacers = 0;
    01069
    01070     uint nbuttons = 0;
    01071     /* First initialise some variables... */
    01072     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
    01073       child_wid->SetupSmallestSize(w, init_array);
    01074       this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom);
    01075       if (this->IsButton(child_wid->type)) {
    01076         nbuttons++;
    01077         this->smallest_x = max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right);
    01078       } else if (child_wid->type == NWID_SPACER) {
    01079         this->spacers++;
    01080       }
    01081     }
    01082
    01083     /* ... then in a second pass make sure the 'current' heights are set. Won't change ever. */
    01084     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
    01085       child_wid->current_y = this->smallest_y;
    01086       if (!this->IsButton(child_wid->type)) {
    01087         child_wid->current_x = child_wid->smallest_x;
    01088       }
    01089     }
    01090     *_preferred_toolbar_size = nbuttons * this->smallest_x;
    01091   }
    01092
    01093   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl)
    01094   {
    01095     assert(given_width >= this->smallest_x && given_height >= this->smallest_y);
    01096
    01097     this->pos_x = x;
    01098     this->pos_y = y;
    01099     this->current_x = given_width;
    01100     this->current_y = given_height;
    01101
    01102     /* Figure out what are the visible buttons */
    01103     memset(this->visible, 0, sizeof(this->visible));
    01104     uint arrangable_count, button_count, spacer_count;
    01105     const byte *arrangement = GetButtonArrangement(given_width, arrangable_count, button_count, spacer_count);
    01106     for (uint i = 0; i < arrangable_count; i++) {
    01107       this->visible[arrangement[i]] = true;
    01108     }
    01109
    01110     /* Create us ourselves a quick lookup table */
    01111     NWidgetBase *widgets[TBN_END];
    01112     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
    01113       if (child_wid->type == NWID_SPACER) continue;
    01114       widgets[((NWidgetCore*)child_wid)->index] = child_wid;
    01115     }
    01116
    01117     /* Now assign the widgets to their rightful place */
    01118     uint position = 0; // Place to put next child relative to origin of the container.
    01119     uint spacer_space = max(0, (int)given_width - (int)(button_count * this->smallest_x)); // Remaining spacing for 'spacer' widgets
    01120     uint button_space = given_width - spacer_space; // Remaining spacing for the buttons
    01121     uint spacer_i = 0;
    01122     uint button_i = 0;
    01123
    01124     /* Index into the arrangement indices. The macro lastof cannot be used here! */
    01125     const byte *cur_wid = rtl ? &arrangement[arrangable_count - 1] : arrangement;
    01126     for (uint i = 0; i < arrangable_count; i++) {
    01127       NWidgetBase *child_wid = widgets[*cur_wid];
    01128       /* If we have to give space to the spacers, do that */
    01129       if (spacer_space != 0) {
    01130         NWidgetBase *possible_spacer = rtl ? child_wid->next : child_wid->prev;
    01131         if (possible_spacer != NULL && possible_spacer->type == NWID_SPACER) {
    01132           uint add = spacer_space / (spacer_count - spacer_i);
    01133           position += add;
    01134           spacer_space -= add;
    01135           spacer_i++;
    01136         }
    01137       }
    01138
    01139       /* Buttons can be scaled, the others not. */
    01140       if (this->IsButton(child_wid->type)) {
    01141         child_wid->current_x = button_space / (button_count - button_i);
    01142         button_space -= child_wid->current_x;
    01143         button_i++;
    01144       }
    01145       child_wid->AssignSizePosition(sizing, x + position, y, child_wid->current_x, this->current_y, rtl);
    01146       position += child_wid->current_x;
    01147
    01148       if (rtl) {
    01149         cur_wid--;
    01150       } else {
    01151         cur_wid++;
    01152       }
    01153     }
    01154   }
    01155
    01156   /* virtual */ void Draw(const Window *w)
    01157   {
    01158     /* Draw brown-red toolbar bg. */
    01159     GfxFillRect(this->pos_x, this->pos_y, this->pos_x + this->current_x - 1, this->pos_y + this->current_y - 1, 0xB2);
    01160     GfxFillRect(this->pos_x, this->pos_y, this->pos_x + this->current_x - 1, this->pos_y + this->current_y - 1, 0xB4, FILLRECT_CHECKER);
    01161
    01162     bool rtl = _current_text_dir == TD_RTL;
    01163     for (NWidgetBase *child_wid = rtl ? this->tail : this->head; child_wid != NULL; child_wid = rtl ? child_wid->prev : child_wid->next) {
    01164       if (child_wid->type == NWID_SPACER) continue;
    01165       if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
    01166
    01167       child_wid->Draw(w);
    01168     }
    01169   }
    01170
    01171   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y)
    01172   {
    01173     if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL;
    01174
    01175     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
    01176       if (child_wid->type == NWID_SPACER) continue;
    01177       if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
    01178
    01179       NWidgetCore *nwid = child_wid->GetWidgetFromPos(x, y);
    01180       if (nwid != NULL) return nwid;
    01181     }
    01182     return NULL;
    01183   }
    01184
    01193   virtual const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const = 0;
    01194 };
    01195
    01197 class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
    01198   /* virtual */ const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
    01199   {
    01200     static const uint SMALLEST_ARRANGEMENT = 14;
    01201     static const uint BIGGEST_ARRANGEMENT  = 19;
    01202     static const byte arrange14[] = {
    01203       0,  1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 27,
    01204       2,  3,  4,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 27,
    01205     };
    01206     static const byte arrange15[] = {
    01207       0,  1,  4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
    01208       0,  2,  4,  3,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 27,
    01209     };
    01210     static const byte arrange16[] = {
    01211       0,  1,  2,  4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
    01212       0,  1,  3,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 17, 18, 27,
    01213     };
    01214     static const byte arrange17[] = {
    01215       0,  1,  2,  4,  6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
    01216       0,  1,  3,  4,  6,  5,  7,  8,  9, 10, 12, 24, 25, 26, 17, 18, 27,
    01217     };
    01218     static const byte arrange18[] = {
    01219       0,  1,  2,  4,  5,  6,  7,  8,  9, 12, 19, 20, 21, 22, 23, 17, 18, 27,
    01220       0,  1,  3,  4,  5,  6,  7, 10, 13, 14, 15, 16, 24, 25, 26, 17, 18, 27,
    01221     };
    01222     static const byte arrange19[] = {
    01223       0,  1,  2,  4,  5,  6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 27,
    01224       0,  1,  3,  4,  7,  8,  9, 10, 12, 25, 19, 20, 21, 22, 23, 26, 17, 18, 27,
    01225     };
    01226     static const byte arrange_all[] = {
    01227       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,
    01228     };
    01229
    01230     /* If at least BIGGEST_ARRANGEMENT fit, just spread all the buttons nicely */
    01231     uint full_buttons = max(CeilDiv(width, this->smallest_x), SMALLEST_ARRANGEMENT);
    01232     if (full_buttons > BIGGEST_ARRANGEMENT) {
    01233       button_count = arrangable_count = lengthof(arrange_all);
    01234       spacer_count = this->spacers;
    01235       return arrange_all;
    01236     }
    01237
    01238     /* Introduce the split toolbar */
    01239     static const byte * const arrangements[] = { arrange14, arrange15, arrange16, arrange17, arrange18, arrange19 };
    01240
    01241     button_count = arrangable_count = full_buttons;
    01242     spacer_count = this->spacers;
    01243     return arrangements[full_buttons - SMALLEST_ARRANGEMENT] + ((_toolbar_mode == TB_LOWER) ? full_buttons : 0);
    01244   }
    01245 };
    01246
    01248 class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer {
    01249   uint panel_widths[2];
    01250
    01251   void SetupSmallestSize(Window *w, bool init_array)
    01252   {
    01253     this->NWidgetToolbarContainer::SetupSmallestSize(w, init_array);
    01254
    01255     /* Find the size of panel_widths */
    01256     uint i = 0;
    01257     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
    01258       if (child_wid->type == NWID_SPACER || this->IsButton(child_wid->type)) continue;
    01259
    01260       assert(i < lengthof(this->panel_widths));
    01261       this->panel_widths[i++] = child_wid->current_x;
    01262       *_preferred_toolbar_size += child_wid->current_x;
    01263     }
    01264   }
    01265
    01266   /* virtual */ const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
    01267   {
    01268     static const byte arrange_all[] = {
    01269       0, 1, 2, 3, 4, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24, 26,
    01270     };
    01271     static const byte arrange_nopanel[] = {
    01272       0, 1, 2, 3, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24, 26,
    01273     };
    01274     static const byte arrange_switch[] = {
    01275       18,  8, 11, 12, 13, 14, 15, 16, 17, 27,
    01276        0,  1,  2,  3, 18,  9, 10, 24, 26, 27,
    01277     };
    01278
    01279     /* If we can place all buttons *and* the panels, show them. */
    01280     uint min_full_width = (lengthof(arrange_all) - lengthof(this->panel_widths)) * this->smallest_x + this->panel_widths[0] + this->panel_widths[1];
    01281     if (width >= min_full_width) {
    01282       width -= this->panel_widths[0] + this->panel_widths[1];
    01283       arrangable_count = lengthof(arrange_all);
    01284       button_count = arrangable_count - 2;
    01285       spacer_count = this->spacers;
    01286       return arrange_all;
    01287     }
    01288
    01289     /* 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 */
    01290     uint min_small_width = (lengthof(arrange_switch) - lengthof(this->panel_widths)) * this->smallest_x / 2 + this->panel_widths[1];
    01291     if (width > min_small_width) {
    01292       width -= this->panel_widths[1];
    01293       arrangable_count = lengthof(arrange_nopanel);
    01294       button_count = arrangable_count - 1;
    01295       spacer_count = this->spacers - 1;
    01296       return arrange_nopanel;
    01297     }
    01298
    01299     /* Split toolbar */
    01300     width -= this->panel_widths[1];
    01301     arrangable_count = lengthof(arrange_switch) / 2;
    01302     button_count = arrangable_count - 1;
    01303     spacer_count = 0;
    01304     return arrange_switch + ((_toolbar_mode == TB_LOWER) ? arrangable_count : 0);
    01305   }
    01306 };
    01307
    01308 /* --- Toolbar handling for the 'normal' case */
    01309
    01310 typedef CallBackFunction ToolbarButtonProc(Window *w);
    01311
    01312 static ToolbarButtonProc * const _toolbar_button_procs[] = {
    01313   ToolbarPauseClick,
    01314   ToolbarFastForwardClick,
    01315   ToolbarOptionsClick,
    01316   ToolbarSaveClick,
    01317   ToolbarMapClick,
    01318   ToolbarTownClick,
    01319   ToolbarSubsidiesClick,
    01320   ToolbarStationsClick,
    01321   ToolbarFinancesClick,
    01322   ToolbarCompaniesClick,
    01323   ToolbarGraphsClick,
    01324   ToolbarLeagueClick,
    01325   ToolbarIndustryClick,
    01326   ToolbarTrainClick,
    01327   ToolbarRoadClick,
    01328   ToolbarShipClick,
    01329   ToolbarAirClick,
    01330   ToolbarZoomInClick,
    01331   ToolbarZoomOutClick,
    01332   ToolbarBuildRailClick,
    01333   ToolbarBuildRoadClick,
    01334   ToolbarBuildWaterClick,
    01335   ToolbarBuildAirClick,
    01336   ToolbarForestClick,
    01337   ToolbarMusicClick,
    01338   ToolbarNewspaperClick,
    01339   ToolbarHelpClick,
    01340   ToolbarSwitchClick,
    01341 };
    01342
    01343 enum MainToolbarHotkeys {
    01344   MTHK_PAUSE,
    01345   MTHK_FASTFORWARD,
    01346   MTHK_SETTINGS,
    01347   MTHK_SAVEGAME,
    01348   MTHK_LOADGAME,
    01349   MTHK_SMALLMAP,
    01350   MTHK_TOWNDIRECTORY,
    01351   MTHK_SUBSIDIES,
    01352   MTHK_STATIONS,
    01353   MTHK_FINANCES,
    01354   MTHK_COMPANIES,
    01355   MTHK_GRAPHS,
    01356   MTHK_LEAGUE,
    01357   MTHK_INDUSTRIES,
    01358   MTHK_TRAIN_LIST,
    01359   MTHK_ROADVEH_LIST,
    01360   MTHK_SHIP_LIST,
    01361   MTHK_AIRCRAFT_LIST,
    01362   MTHK_ZOOM_IN,
    01363   MTHK_ZOOM_OUT,
    01364   MTHK_BUILD_RAIL,
    01365   MTHK_BUILD_ROAD,
    01366   MTHK_BUILD_DOCKS,
    01367   MTHK_BUILD_AIRPORT,
    01368   MTHK_BUILD_TREES,
    01369   MTHK_MUSIC,
    01370   MTHK_AI_DEBUG,
    01371   MTHK_SMALL_SCREENSHOT,
    01372   MTHK_ZOOMEDIN_SCREENSHOT,
    01373   MTHK_GIANT_SCREENSHOT,
    01374   MTHK_CHEATS,
    01375   MTHK_TERRAFORM,
    01376   MTHK_EXTRA_VIEWPORT,
    01377   MTHK_CLIENT_LIST,
    01378   MTHK_SIGN_LIST,
    01379 };
    01380
    01382 struct MainToolbarWindow : Window {
    01383   CallBackFunction last_started_action;
    01384
    01385   MainToolbarWindow(const WindowDesc *desc) : Window()
    01386   {
    01387     this->InitNested(desc, 0);
    01388
    01389     this->last_started_action = CBF_NONE;
    01390     CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
    01391     this->SetWidgetDisabledState(TBN_PAUSE, _networking && !_network_server); // if not server, disable pause button
    01392     this->SetWidgetDisabledState(TBN_FASTFORWARD, _networking); // if networking, disable fast-forward button
    01393     PositionMainToolbar(this);
    01394     DoZoomInOutWindow(ZOOM_NONE, this);
    01395   }
    01396
    01397   virtual void OnPaint()
    01398   {
    01399     /* If spectator, disable all construction buttons
    01400      * ie : Build road, rail, ships, airports and landscaping
    01401      * Since enabled state is the default, just disable when needed */
    01402     this->SetWidgetsDisabledState(_local_company == COMPANY_SPECTATOR, TBN_RAILS, TBN_ROADS, TBN_WATER, TBN_AIR, TBN_LANDSCAPE, WIDGET_LIST_END);
    01403     /* disable company list drop downs, if there are no companies */
    01404     this->SetWidgetsDisabledState(Company::GetNumItems() == 0, TBN_STATIONS, TBN_FINANCES, TBN_TRAINS, TBN_ROADVEHS, TBN_SHIPS, TBN_AIRCRAFTS, WIDGET_LIST_END);
    01405
    01406     this->SetWidgetDisabledState(TBN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN));
    01407     this->SetWidgetDisabledState(TBN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT));
    01408
    01409     this->DrawWidgets();
    01410   }
    01411
    01412   virtual void OnClick(Point pt, int widget, int click_count)
    01413   {
    01414     if (_game_mode != GM_MENU && !this->IsWidgetDisabled(widget)) _toolbar_button_procs[widget](this);
    01415   }
    01416
    01417   virtual void OnDropdownSelect(int widget, int index)
    01418   {
    01419     CallBackFunction cbf = _menu_clicked_procs[widget](index);
    01420     if (cbf != CBF_NONE) this->last_started_action = cbf;
    01421   }
    01422
    01423   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
    01424   {
    01425     switch (CheckHotkeyMatch(maintoolbar_hotkeys, keycode, this)) {
    01426       case MTHK_PAUSE: ToolbarPauseClick(this); break;
    01427       case MTHK_FASTFORWARD: ToolbarFastForwardClick(this); break;
    01428       case MTHK_SETTINGS: ShowGameOptions(); break;
    01429       case MTHK_SAVEGAME: MenuClickSaveLoad(); break;
    01430       case MTHK_LOADGAME: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
    01431       case MTHK_SMALLMAP: ShowSmallMap(); break;
    01432       case MTHK_TOWNDIRECTORY: ShowTownDirectory(); break;
    01433       case MTHK_SUBSIDIES: ShowSubsidiesList(); break;
    01434       case MTHK_STATIONS: ShowCompanyStations(_local_company); break;
    01435       case MTHK_FINANCES: ShowCompanyFinances(_local_company); break;
    01436       case MTHK_COMPANIES: ShowCompany(_local_company); break;
    01437       case MTHK_GRAPHS: ShowOperatingProfitGraph(); break;
    01438       case MTHK_LEAGUE: ShowCompanyLeagueTable(); break;
    01439       case MTHK_INDUSTRIES: ShowBuildIndustryWindow(); break;
    01440       case MTHK_TRAIN_LIST: ShowVehicleListWindow(_local_company, VEH_TRAIN); break;
    01441       case MTHK_ROADVEH_LIST: ShowVehicleListWindow(_local_company, VEH_ROAD); break;
    01442       case MTHK_SHIP_LIST: ShowVehicleListWindow(_local_company, VEH_SHIP); break;
    01443       case MTHK_AIRCRAFT_LIST: ShowVehicleListWindow(_local_company, VEH_AIRCRAFT); break;
    01444       case MTHK_ZOOM_IN: ToolbarZoomInClick(this); break;
    01445       case MTHK_ZOOM_OUT: ToolbarZoomOutClick(this); break;
    01446       case MTHK_BUILD_RAIL: if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype); break;
    01447       case MTHK_BUILD_ROAD: ShowBuildRoadToolbar(_last_built_roadtype); break;
    01448       case MTHK_BUILD_DOCKS: ShowBuildDocksToolbar(); break;
    01449       case MTHK_BUILD_AIRPORT: if (CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) ShowBuildAirToolbar(); break;
    01450       case MTHK_BUILD_TREES: ShowBuildTreesToolbar(); break;
    01451       case MTHK_MUSIC: ShowMusicWindow(); break;
    01452       case MTHK_AI_DEBUG: ShowAIDebugWindow(); break;
    01453       case MTHK_SMALL_SCREENSHOT: MenuClickSmallScreenshot(); break;
    01454       case MTHK_ZOOMEDIN_SCREENSHOT: MenuClickZoomedInScreenshot(); break;
    01455       case MTHK_GIANT_SCREENSHOT: MenuClickWorldScreenshot(); break;
    01456       case MTHK_CHEATS: if (!_networking) ShowCheatWindow(); break;
    01457       case MTHK_TERRAFORM: ShowTerraformToolbar(); break;
    01458       case MTHK_EXTRA_VIEWPORT: ShowExtraViewPortWindowForTileUnderCursor(); break;
    01459 #ifdef ENABLE_NETWORK
    01460       case MTHK_CLIENT_LIST: if (_networking) ShowClientList(); break;
    01461 #endif
    01462       case MTHK_SIGN_LIST: ShowSignList(); break;
    01463       default: return ES_NOT_HANDLED;
    01464     }
    01465     return ES_HANDLED;
    01466   }
    01467
    01468   virtual void OnPlaceObject(Point pt, TileIndex tile)
    01469   {
    01470     switch (this->last_started_action) {
    01471       case CBF_PLACE_SIGN:
    01472         PlaceProc_Sign(tile);
    01473         break;
    01474
    01475       case CBF_PLACE_LANDINFO:
    01476         ShowLandInfo(tile);
    01477         break;
    01478
    01479       default: NOT_REACHED();
    01480     }
    01481   }
    01482
    01483   virtual void OnTick()
    01484   {
    01485     if (this->IsWidgetLowered(TBN_PAUSE) != !!_pause_mode) {
    01486       this->ToggleWidgetLoweredState(TBN_PAUSE);
    01487       this->SetWidgetDirty(TBN_PAUSE);
    01488     }
    01489
    01490     if (this->IsWidgetLowered(TBN_FASTFORWARD) != !!_fast_forward) {
    01491       this->ToggleWidgetLoweredState(TBN_FASTFORWARD);
    01492       this->SetWidgetDirty(TBN_FASTFORWARD);
    01493     }
    01494   }
    01495
    01496   virtual void OnTimeout()
    01497   {
    01498     /* We do not want to automatically raise the pause, fast forward and
    01499      * switchbar buttons; they have to stay down when pressed etc. */
    01500     for (uint i = TBN_SETTINGS; i < TBN_SWITCHBAR; i++) {
    01501       if (this->IsWidgetLowered(i)) {
    01502         this->RaiseWidget(i);
    01503         this->SetWidgetDirty(i);
    01504       }
    01505     }
    01506   }
    01507
    01513   virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
    01514   {
    01515     if (!gui_scope) return;
    01516     if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, TBN_ZOOMIN, TBN_ZOOMOUT);
    01517   }
    01518
    01519   static Hotkey<MainToolbarWindow> maintoolbar_hotkeys[];
    01520 };
    01521
    01522 const uint16 _maintoolbar_pause_keys[] = {WKC_F1, WKC_PAUSE, 0};
    01523 const uint16 _maintoolbar_zoomin_keys[] = {WKC_NUM_PLUS, WKC_EQUALS, WKC_SHIFT | WKC_EQUALS, WKC_SHIFT | WKC_F5, 0};
    01524 const uint16 _maintoolbar_zoomout_keys[] = {WKC_NUM_MINUS, WKC_MINUS, WKC_SHIFT | WKC_MINUS, WKC_SHIFT | WKC_F6, 0};
    01525 const uint16 _maintoolbar_smallmap_keys[] = {WKC_F4, 'M', 0};
    01526
    01527 Hotkey<MainToolbarWindow> MainToolbarWindow::maintoolbar_hotkeys[] = {
    01528   Hotkey<MainToolbarWindow>(_maintoolbar_pause_keys, "pause", MTHK_PAUSE),
    01529   Hotkey<MainToolbarWindow>((uint16)0, "fastforward", MTHK_FASTFORWARD),
    01530   Hotkey<MainToolbarWindow>(WKC_F2, "settings", MTHK_SETTINGS),
    01531   Hotkey<MainToolbarWindow>(WKC_F3, "saveload", MTHK_SAVEGAME),
    01532   Hotkey<MainToolbarWindow>((uint16)0, "load_game", MTHK_LOADGAME),
    01533   Hotkey<MainToolbarWindow>(_maintoolbar_smallmap_keys, "smallmap", MTHK_SMALLMAP),
    01534   Hotkey<MainToolbarWindow>(WKC_F5, "town_list", MTHK_TOWNDIRECTORY),
    01535   Hotkey<MainToolbarWindow>(WKC_F6, "subsidies", MTHK_SUBSIDIES),
    01536   Hotkey<MainToolbarWindow>(WKC_F7, "station_list", MTHK_STATIONS),
    01537   Hotkey<MainToolbarWindow>(WKC_F8, "finances", MTHK_FINANCES),
    01538   Hotkey<MainToolbarWindow>(WKC_F9, "companies", MTHK_COMPANIES),
    01539   Hotkey<MainToolbarWindow>(WKC_F10, "graphs", MTHK_GRAPHS),
    01540   Hotkey<MainToolbarWindow>(WKC_F11, "league", MTHK_LEAGUE),
    01541   Hotkey<MainToolbarWindow>(WKC_F12, "industry_list", MTHK_INDUSTRIES),
    01542   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F1, "train_list", MTHK_TRAIN_LIST),
    01543   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F2, "roadveh_list", MTHK_ROADVEH_LIST),
    01544   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F3, "ship_list", MTHK_SHIP_LIST),
    01545   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F4, "aircraft_list", MTHK_AIRCRAFT_LIST),
    01546   Hotkey<MainToolbarWindow>(_maintoolbar_zoomin_keys, "zoomin", MTHK_ZOOM_IN),
    01547   Hotkey<MainToolbarWindow>(_maintoolbar_zoomout_keys, "zoomout", MTHK_ZOOM_OUT),
    01548   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F7, "build_rail", MTHK_BUILD_RAIL),
    01549   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F8, "build_road", MTHK_BUILD_ROAD),
    01550   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F9, "build_docks", MTHK_BUILD_DOCKS),
    01551   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F10, "build_airport", MTHK_BUILD_AIRPORT),
    01552   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F11, "build_trees", MTHK_BUILD_TREES),
    01553   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F12, "music", MTHK_MUSIC),
    01554   Hotkey<MainToolbarWindow>((uint16)0, "ai_debug", MTHK_AI_DEBUG),
    01555   Hotkey<MainToolbarWindow>(WKC_CTRL  | 'S', "small_screenshot", MTHK_SMALL_SCREENSHOT),
    01556   Hotkey<MainToolbarWindow>(WKC_CTRL  | 'P', "zoomedin_screenshot", MTHK_ZOOMEDIN_SCREENSHOT),
    01557   Hotkey<MainToolbarWindow>((uint16)0, "giant_screenshot", MTHK_GIANT_SCREENSHOT),
    01558   Hotkey<MainToolbarWindow>(WKC_CTRL | WKC_ALT | 'C', "cheats", MTHK_CHEATS),
    01559   Hotkey<MainToolbarWindow>('L', "terraform", MTHK_TERRAFORM),
    01560   Hotkey<MainToolbarWindow>('V', "extra_viewport", MTHK_EXTRA_VIEWPORT),
    01561 #ifdef ENABLE_NETWORK
    01562   Hotkey<MainToolbarWindow>((uint16)0, "client_list", MTHK_CLIENT_LIST),
    01563 #endif
    01564   Hotkey<MainToolbarWindow>((uint16)0, "sign_list", MTHK_SIGN_LIST),
    01565   HOTKEY_LIST_END(MainToolbarWindow)
    01566 };
    01567 Hotkey<MainToolbarWindow> *_maintoolbar_hotkeys = MainToolbarWindow::maintoolbar_hotkeys;
    01568
    01569 static NWidgetBase *MakeMainToolbar(int *biggest_index)
    01570 {
    01572   static const SpriteID toolbar_button_sprites[] = {
    01573     SPR_IMG_PAUSE,           // TBN_PAUSE
    01574     SPR_IMG_FASTFORWARD,     // TBN_FASTFORWARD
    01575     SPR_IMG_SETTINGS,        // TBN_SETTINGS
    01576     SPR_IMG_SAVE,            // TBN_SAVEGAME
    01577     SPR_IMG_SMALLMAP,        // TBN_SMALLMAP
    01578     SPR_IMG_TOWN,            // TBN_TOWNDIRECTORY
    01579     SPR_IMG_SUBSIDIES,       // TBN_SUBSIDIES
    01580     SPR_IMG_COMPANY_LIST,    // TBN_STATIONS
    01581     SPR_IMG_COMPANY_FINANCE, // TBN_FINANCES
    01582     SPR_IMG_COMPANY_GENERAL, // TBN_COMPANIES
    01583     SPR_IMG_GRAPHS,          // TBN_GRAPHICS
    01584     SPR_IMG_COMPANY_LEAGUE,  // TBN_LEAGUE
    01585     SPR_IMG_INDUSTRY,        // TBN_INDUSTRIES
    01586     SPR_IMG_TRAINLIST,       // TBN_TRAINS
    01587     SPR_IMG_TRUCKLIST,       // TBN_ROADVEHS
    01588     SPR_IMG_SHIPLIST,        // TBN_SHIPS
    01589     SPR_IMG_AIRPLANESLIST,   // TBN_AIRCRAFTS
    01590     SPR_IMG_ZOOMIN,          // TBN_ZOOMIN
    01591     SPR_IMG_ZOOMOUT,         // TBN_ZOOMOUT
    01592     SPR_IMG_BUILDRAIL,       // TBN_RAILS
    01593     SPR_IMG_BUILDROAD,       // TBN_ROADS
    01594     SPR_IMG_BUILDWATER,      // TBN_WATER
    01595     SPR_IMG_BUILDAIR,        // TBN_AIR
    01596     SPR_IMG_LANDSCAPING,     // TBN_LANDSCAPE
    01597     SPR_IMG_MUSIC,           // TBN_MUSICSOUND
    01598     SPR_IMG_MESSAGES,        // TBN_NEWSREPORT
    01599     SPR_IMG_QUERY,           // TBN_HELP
    01600     SPR_IMG_SWITCH_TOOLBAR,  // TBN_SWITCHBAR
    01601   };
    01602
    01603   NWidgetMainToolbarContainer *hor = new NWidgetMainToolbarContainer();
    01604   for (uint i = 0; i < TBN_END; i++) {
    01605     switch (i) {
    01606       case 4: case 8: case 13: case 17: case 19: case 24: hor->Add(new NWidgetSpacer(0, 0)); break;
    01607     }
    01608     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));
    01609   }
    01610
    01611   *biggest_index = max<int>(*biggest_index, TBN_SWITCHBAR);
    01612   return hor;
    01613 }
    01614
    01615 static const NWidgetPart _nested_toolbar_normal_widgets[] = {
    01616   NWidgetFunction(MakeMainToolbar),
    01617 };
    01618
    01619 static WindowDesc _toolb_normal_desc(
    01620   WDP_MANUAL, 640, 22,
    01621   WC_MAIN_TOOLBAR, WC_NONE,
    01622   WDF_NO_FOCUS,
    01623   _nested_toolbar_normal_widgets, lengthof(_nested_toolbar_normal_widgets)
    01624 );
    01625
    01626
    01627 /* --- Toolbar handling for the scenario editor */
    01628
    01629 static ToolbarButtonProc * const _scen_toolbar_button_procs[] = {
    01630   ToolbarPauseClick,
    01631   ToolbarFastForwardClick,
    01632   ToolbarOptionsClick,
    01633   ToolbarScenSaveOrLoad,
    01634   ToolbarBtn_NULL,
    01635   ToolbarScenDatePanel,
    01636   ToolbarScenDateBackward,
    01637   ToolbarScenDateForward,
    01638   ToolbarScenMapTownDir,
    01639   ToolbarZoomInClick,
    01640   ToolbarZoomOutClick,
    01641   ToolbarScenGenLand,
    01642   ToolbarScenGenTown,
    01643   ToolbarScenGenIndustry,
    01644   ToolbarScenBuildRoad,
    01645   ToolbarScenBuildDocks,
    01646   ToolbarScenPlantTrees,
    01647   ToolbarScenPlaceSign,
    01648   ToolbarBtn_NULL,
    01649   NULL,
    01650   NULL,
    01651   NULL,
    01652   NULL,
    01653   NULL,
    01654   ToolbarMusicClick,
    01655   NULL,
    01656   ToolbarHelpClick,
    01657   ToolbarSwitchClick,
    01658 };
    01659
    01660 enum MainToolbarEditorHotkeys {
    01661   MTEHK_PAUSE,
    01662   MTEHK_FASTFORWARD,
    01663   MTEHK_SETTINGS,
    01664   MTEHK_SAVEGAME,
    01665   MTEHK_GENLAND,
    01666   MTEHK_GENTOWN,
    01667   MTEHK_GENINDUSTRY,
    01668   MTEHK_BUILD_ROAD,
    01669   MTEHK_BUILD_DOCKS,
    01670   MTEHK_BUILD_TREES,
    01671   MTEHK_SIGN,
    01672   MTEHK_MUSIC,
    01673   MTEHK_LANDINFO,
    01674   MTEHK_SMALL_SCREENSHOT,
    01675   MTEHK_ZOOMEDIN_SCREENSHOT,
    01676   MTEHK_GIANT_SCREENSHOT,
    01677   MTEHK_ZOOM_IN,
    01678   MTEHK_ZOOM_OUT,
    01679   MTEHK_TERRAFORM,
    01680   MTEHK_SMALLMAP,
    01681   MTEHK_EXTRA_VIEWPORT,
    01682 };
    01683
    01684 struct ScenarioEditorToolbarWindow : Window {
    01685   CallBackFunction last_started_action;
    01686
    01687   ScenarioEditorToolbarWindow(const WindowDesc *desc) : Window()
    01688   {
    01689     this->InitNested(desc, 0);
    01690
    01691     this->last_started_action = CBF_NONE;
    01692     CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
    01693     PositionMainToolbar(this);
    01694     DoZoomInOutWindow(ZOOM_NONE, this);
    01695   }
    01696
    01697   virtual void OnPaint()
    01698   {
    01699     this->SetWidgetDisabledState(TBSE_DATEBACKWARD, _settings_game.game_creation.starting_year <= MIN_YEAR);
    01700     this->SetWidgetDisabledState(TBSE_DATEFORWARD, _settings_game.game_creation.starting_year >= MAX_YEAR);
    01701
    01702     this->DrawWidgets();
    01703   }
    01704
    01705   virtual void DrawWidget(const Rect &r, int widget) const
    01706   {
    01707     switch (widget) {
    01708       case TBSE_DATEPANEL:
    01709         SetDParam(0, ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
    01710         DrawString(r.left, r.right, (this->height - FONT_HEIGHT_NORMAL) / 2, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_HOR_CENTER);
    01711         break;
    01712
    01713       case TBSE_SPACERPANEL: {
    01714         int height = r.bottom - r.top;
    01715         if (height > 2 * FONT_HEIGHT_NORMAL) {
    01716           DrawString(r.left, r.right, (height + 1) / 2 - FONT_HEIGHT_NORMAL, STR_SCENEDIT_TOOLBAR_OPENTTD, TC_FROMSTRING, SA_HOR_CENTER);
    01717           DrawString(r.left, r.right, (height + 1) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER);
    01718         } else {
    01719           DrawString(r.left, r.right, (height - FONT_HEIGHT_NORMAL) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER);
    01720         }
    01721         break;
    01722       }
    01723     }
    01724   }
    01725
    01726   virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
    01727   {
    01728     switch (widget) {
    01729       case TBSE_SPACERPANEL:
    01730         size->width = max(GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_OPENTTD).width, GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR).width) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
    01731         break;
    01732
    01733       case TBSE_DATEPANEL:
    01734         SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1));
    01735         *size = GetStringBoundingBox(STR_WHITE_DATE_LONG);
    01736         size->height = max(size->height, GetSpriteSize(SPR_IMG_SAVE).height + WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM);
    01737         break;
    01738     }
    01739   }
    01740
    01741   virtual void OnClick(Point pt, int widget, int click_count)
    01742   {
    01743     if (_game_mode == GM_MENU) return;
    01744     CallBackFunction cbf = _scen_toolbar_button_procs[widget](this);
    01745     if (cbf != CBF_NONE) this->last_started_action = cbf;
    01746   }
    01747
    01748   virtual void OnDropdownSelect(int widget, int index)
    01749   {
    01750     /* The map button is in a different location on the scenario
    01751      * editor toolbar, so we need to adjust for it. */
    01752     if (widget == TBSE_SMALLMAP) widget = TBN_SMALLMAP;
    01753     CallBackFunction cbf = _menu_clicked_procs[widget](index);
    01754     if (cbf != CBF_NONE) this->last_started_action = cbf;
    01755     SndPlayFx(SND_15_BEEP);
    01756   }
    01757
    01758   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
    01759   {
    01760     CallBackFunction cbf = CBF_NONE;
    01761     switch (CheckHotkeyMatch(scenedit_maintoolbar_hotkeys, keycode, this)) {
    01762       case MTEHK_PAUSE:               ToolbarPauseClick(this); break;
    01763       case MTEHK_FASTFORWARD:         ToolbarFastForwardClick(this); break;
    01764       case MTEHK_SETTINGS:            ShowGameOptions(); break;
    01765       case MTEHK_SAVEGAME:            MenuClickSaveLoad(); break;
    01766       case MTEHK_GENLAND:             ToolbarScenGenLand(this); break;
    01767       case MTEHK_GENTOWN:             ToolbarScenGenTown(this); break;
    01768       case MTEHK_GENINDUSTRY:         ToolbarScenGenIndustry(this); break;
    01769       case MTEHK_BUILD_ROAD:          ToolbarScenBuildRoad(this); break;
    01770       case MTEHK_BUILD_DOCKS:         ToolbarScenBuildDocks(this); break;
    01771       case MTEHK_BUILD_TREES:         ToolbarScenPlantTrees(this); break;
    01772       case MTEHK_SIGN:                cbf = ToolbarScenPlaceSign(this); break;
    01773       case MTEHK_MUSIC:               ShowMusicWindow(); break;
    01774       case MTEHK_LANDINFO:            cbf = PlaceLandBlockInfo(); break;
    01775       case MTEHK_SMALL_SCREENSHOT:    MenuClickSmallScreenshot(); break;
    01776       case MTEHK_ZOOMEDIN_SCREENSHOT: MenuClickZoomedInScreenshot(); break;
    01777       case MTEHK_GIANT_SCREENSHOT:    MenuClickWorldScreenshot(); break;
    01778       case MTEHK_ZOOM_IN:             ToolbarZoomInClick(this); break;
    01779       case MTEHK_ZOOM_OUT:            ToolbarZoomOutClick(this); break;
    01780       case MTEHK_TERRAFORM:           ShowEditorTerraformToolbar(); break;
    01781       case MTEHK_SMALLMAP:            ShowSmallMap(); break;
    01782       case MTEHK_EXTRA_VIEWPORT:      ShowExtraViewPortWindowForTileUnderCursor(); break;
    01783       default: return ES_NOT_HANDLED;
    01784     }
    01785     if (cbf != CBF_NONE) this->last_started_action = cbf;
    01786     return ES_HANDLED;
    01787   }
    01788
    01789   virtual void OnPlaceObject(Point pt, TileIndex tile)
    01790   {
    01791     switch (this->last_started_action) {
    01792       case CBF_PLACE_SIGN:
    01793         PlaceProc_Sign(tile);
    01794         break;
    01795
    01796       case CBF_PLACE_LANDINFO:
    01797         ShowLandInfo(tile);
    01798         break;
    01799
    01800       default: NOT_REACHED();
    01801     }
    01802   }
    01803
    01804   virtual void OnTimeout()
    01805   {
    01806     this->SetWidgetsLoweredState(false, TBSE_DATEBACKWARD, TBSE_DATEFORWARD, WIDGET_LIST_END);
    01807     this->SetWidgetDirty(TBSE_DATEBACKWARD);
    01808     this->SetWidgetDirty(TBSE_DATEFORWARD);
    01809   }
    01810
    01811   virtual void OnTick()
    01812   {
    01813     if (this->IsWidgetLowered(TBSE_PAUSE) != !!_pause_mode) {
    01814       this->ToggleWidgetLoweredState(TBSE_PAUSE);
    01815       this->SetDirty();
    01816     }
    01817
    01818     if (this->IsWidgetLowered(TBSE_FASTFORWARD) != !!_fast_forward) {
    01819       this->ToggleWidgetLoweredState(TBSE_FASTFORWARD);
    01820       this->SetDirty();
    01821     }
    01822   }
    01823
    01829   virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
    01830   {
    01831     if (!gui_scope) return;
    01832     if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, TBSE_ZOOMIN, TBSE_ZOOMOUT);
    01833   }
    01834
    01835   virtual void OnQueryTextFinished(char *str)
    01836   {
    01837     /* Was 'cancel' pressed? */
    01838     if (str == NULL) return;
    01839
    01840     int32 value;
    01841     if (!StrEmpty(str)) {
    01842       value = atoi(str);
    01843     } else {
    01844       /* An empty string means revert to the default */
    01845       value = DEF_START_YEAR;
    01846     }
    01847     _settings_game.game_creation.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
    01848     SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
    01849
    01850     this->SetDirty();
    01851   }
    01852
    01853   static Hotkey<ScenarioEditorToolbarWindow> scenedit_maintoolbar_hotkeys[];
    01854 };
    01855
    01856 Hotkey<ScenarioEditorToolbarWindow> ScenarioEditorToolbarWindow::scenedit_maintoolbar_hotkeys[] = {
    01857   Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_pause_keys, "pause", MTEHK_PAUSE),
    01858   Hotkey<ScenarioEditorToolbarWindow>((uint16)0, "fastforward", MTEHK_FASTFORWARD),
    01859   Hotkey<ScenarioEditorToolbarWindow>(WKC_F2, "settings", MTEHK_SETTINGS),
    01860   Hotkey<ScenarioEditorToolbarWindow>(WKC_F3, "saveload", MTEHK_SAVEGAME),
    01861   Hotkey<ScenarioEditorToolbarWindow>(WKC_F4, "gen_land", MTEHK_GENLAND),
    01862   Hotkey<ScenarioEditorToolbarWindow>(WKC_F5, "gen_town", MTEHK_GENTOWN),
    01863   Hotkey<ScenarioEditorToolbarWindow>(WKC_F6, "gen_industry", MTEHK_GENINDUSTRY),
    01864   Hotkey<ScenarioEditorToolbarWindow>(WKC_F7, "build_road", MTEHK_BUILD_ROAD),
    01865   Hotkey<ScenarioEditorToolbarWindow>(WKC_F8, "build_docks", MTEHK_BUILD_DOCKS),
    01866   Hotkey<ScenarioEditorToolbarWindow>(WKC_F9, "build_trees", MTEHK_BUILD_TREES),
    01867   Hotkey<ScenarioEditorToolbarWindow>(WKC_F10, "build_sign", MTEHK_SIGN),
    01868   Hotkey<ScenarioEditorToolbarWindow>(WKC_F11, "music", MTEHK_MUSIC),
    01869   Hotkey<ScenarioEditorToolbarWindow>(WKC_F12, "land_info", MTEHK_LANDINFO),
    01870   Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL  | 'S', "small_screenshot", MTEHK_SMALL_SCREENSHOT),
    01871   Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL  | 'P', "zoomedin_screenshot", MTEHK_ZOOMEDIN_SCREENSHOT),
    01872   Hotkey<ScenarioEditorToolbarWindow>((uint16)0, "giant_screenshot", MTEHK_GIANT_SCREENSHOT),
    01873   Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_zoomin_keys, "zoomin", MTEHK_ZOOM_IN),
    01874   Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_zoomout_keys, "zoomout", MTEHK_ZOOM_OUT),
    01875   Hotkey<ScenarioEditorToolbarWindow>('L', "terraform", MTEHK_TERRAFORM),
    01876   Hotkey<ScenarioEditorToolbarWindow>('M', "smallmap", MTEHK_SMALLMAP),
    01877   Hotkey<ScenarioEditorToolbarWindow>('V', "extra_viewport", MTEHK_EXTRA_VIEWPORT),
    01878   HOTKEY_LIST_END(ScenarioEditorToolbarWindow)
    01879 };
    01880 Hotkey<ScenarioEditorToolbarWindow> *_scenedit_maintoolbar_hotkeys = ScenarioEditorToolbarWindow::scenedit_maintoolbar_hotkeys;
    01881
    01882 static const NWidgetPart _nested_toolb_scen_inner_widgets[] = {
    01883   NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_PAUSE), SetDataTip(SPR_IMG_PAUSE, STR_TOOLBAR_TOOLTIP_PAUSE_GAME),
    01884   NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_FASTFORWARD), SetDataTip(SPR_IMG_FASTFORWARD, STR_TOOLBAR_TOOLTIP_FORWARD),
    01885   NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_SETTINGS), SetDataTip(SPR_IMG_SETTINGS, STR_TOOLBAR_TOOLTIP_OPTIONS),
    01886   NWidget(WWT_IMGBTN_2, COLOUR_GREY, TBSE_SAVESCENARIO), SetDataTip(SPR_IMG_SAVE, STR_SCENEDIT_TOOLBAR_TOOLTIP_SAVE_SCENARIO_LOAD_SCENARIO),
    01887   NWidget(NWID_SPACER),
    01888   NWidget(WWT_PANEL, COLOUR_GREY, TBSE_SPACERPANEL), EndContainer(),
    01889   NWidget(NWID_SPACER),
    01890   NWidget(WWT_PANEL, COLOUR_GREY, TBSE_DATEPANEL_CONTAINER),
    01891     NWidget(NWID_HORIZONTAL), SetPIP(3, 2, 3),
    01892       NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_DATEBACKWARD), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD),
    01893       NWidget(WWT_EMPTY, COLOUR_GREY, TBSE_DATEPANEL), SetDataTip(STR_NULL, STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE),
    01894       NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_DATEFORWARD), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD),
    01895     EndContainer(),
    01896   EndContainer(),
    01897   NWidget(NWID_SPACER),
    01898   NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_SMALLMAP), SetDataTip(SPR_IMG_SMALLMAP, STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY),
    01899   NWidget(NWID_SPACER),
    01900   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_ZOOMIN), SetDataTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN),
    01901   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_ZOOMOUT), SetDataTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT),
    01902   NWidget(NWID_SPACER),
    01903   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_LANDGENERATE), SetDataTip(SPR_IMG_LANDSCAPING, STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION),
    01904   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_TOWNGENERATE), SetDataTip(SPR_IMG_TOWN, STR_SCENEDIT_TOOLBAR_TOWN_GENERATION),
    01905   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_INDUSTRYGENERATE), SetDataTip(SPR_IMG_INDUSTRY, STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION),
    01906   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_BUILDROAD), SetDataTip(SPR_IMG_BUILDROAD, STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION),
    01907   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_BUILDDOCKS), SetDataTip(SPR_IMG_BUILDWATER, STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS),
    01908   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_PLANTTREES), SetDataTip(SPR_IMG_PLANTTREES, STR_SCENEDIT_TOOLBAR_PLANT_TREES),
    01909   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_PLACESIGNS), SetDataTip(SPR_IMG_SIGN, STR_SCENEDIT_TOOLBAR_PLACE_SIGN),
    01910   NWidget(NWID_SPACER),
    01911   NWidget(WWT_IMGBTN, COLOUR_GREY, TBN_MUSICSOUND), SetDataTip(SPR_IMG_MUSIC, STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW),
    01912   NWidget(WWT_IMGBTN, COLOUR_GREY, TBN_HELP), SetDataTip(SPR_IMG_QUERY, STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION),
    01913   NWidget(WWT_IMGBTN, COLOUR_GREY, TBN_SWITCHBAR), SetDataTip(SPR_IMG_SWITCH_TOOLBAR, STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR),
    01914 };
    01915
    01916 static NWidgetBase *MakeScenarioToolbar(int *biggest_index)
    01917 {
    01918   return MakeNWidgets(_nested_toolb_scen_inner_widgets, lengthof(_nested_toolb_scen_inner_widgets), biggest_index, new NWidgetScenarioToolbarContainer());
    01919 }
    01920
    01921 static const NWidgetPart _nested_toolb_scen_widgets[] = {
    01922   NWidgetFunction(MakeScenarioToolbar),
    01923 };
    01924
    01925 static WindowDesc _toolb_scen_desc(
    01926   WDP_MANUAL, 640, 22,
    01927   WC_MAIN_TOOLBAR, WC_NONE,
    01928   WDF_UNCLICK_BUTTONS | WDF_NO_FOCUS,
    01929   _nested_toolb_scen_widgets, lengthof(_nested_toolb_scen_widgets)
    01930 );
    01931
    01932 /* --- Allocating the toolbar --- */
    01933
    01934 void AllocateToolbar()
    01935 {
    01936   /* Clean old GUI values; railtype is (re)set by rail_gui.cpp */
    01937   _last_built_roadtype = ROADTYPE_ROAD;
    01938
    01939   if (_game_mode == GM_EDITOR) {
    01940     _preferred_toolbar_size = &_toolb_scen_desc.default_width;
    01941     new ScenarioEditorToolbarWindow(&_toolb_scen_desc);
    01942   } else {
    01943     _preferred_toolbar_size = &_toolb_normal_desc.default_width;
    01944     new MainToolbarWindow(&_toolb_normal_desc);
    01945   }
    01946 }