# toolbar_gui.cpp

Go to the documentation of this file.

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