# toolbar_gui.cpp

Go to the documentation of this file.

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