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