# toolbar_gui.cpp

Go to the documentation of this file.

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