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