# toolbar_gui.cpp

Go to the documentation of this file.

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