# toolbar_gui.cpp

Go to the documentation of this file.

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