# 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) ? 1 : 2);
    00641   return CBF_NONE;
    00642 }
    00643
    00650 static CallBackFunction MenuClickIndustry(int index)
    00651 {
    00652   switch (index) {
    00653     case 0: ShowIndustryDirectory();   break;
    00654     case 1: ShowBuildIndustryWindow(); break;
    00655   }
    00656   return CBF_NONE;
    00657 }
    00658
    00659 /* --- Trains button menu + 1 helper function for all vehicles. --- */
    00660
    00661 static void ToolbarVehicleClick(Window *w, VehicleType veh)
    00662 {
    00663   const Vehicle *v;
    00664   int dis = ~0;
    00665
    00666   FOR_ALL_VEHICLES(v) {
    00667     if (v->type == veh && v->IsPrimaryVehicle()) ClrBit(dis, v->owner);
    00668   }
    00669   PopupMainCompanyToolbMenu(w, WID_TN_VEHICLE_START + veh, dis);
    00670 }
    00671
    00672
    00673 static CallBackFunction ToolbarTrainClick(Window *w)
    00674 {
    00675   ToolbarVehicleClick(w, VEH_TRAIN);
    00676   return CBF_NONE;
    00677 }
    00678
    00685 static CallBackFunction MenuClickShowTrains(int index)
    00686 {
    00687   ShowVehicleListWindow((CompanyID)index, VEH_TRAIN);
    00688   return CBF_NONE;
    00689 }
    00690
    00691 /* --- Road vehicle button menu --- */
    00692
    00693 static CallBackFunction ToolbarRoadClick(Window *w)
    00694 {
    00695   ToolbarVehicleClick(w, VEH_ROAD);
    00696   return CBF_NONE;
    00697 }
    00698
    00705 static CallBackFunction MenuClickShowRoad(int index)
    00706 {
    00707   ShowVehicleListWindow((CompanyID)index, VEH_ROAD);
    00708   return CBF_NONE;
    00709 }
    00710
    00711 /* --- Ship button menu --- */
    00712
    00713 static CallBackFunction ToolbarShipClick(Window *w)
    00714 {
    00715   ToolbarVehicleClick(w, VEH_SHIP);
    00716   return CBF_NONE;
    00717 }
    00718
    00725 static CallBackFunction MenuClickShowShips(int index)
    00726 {
    00727   ShowVehicleListWindow((CompanyID)index, VEH_SHIP);
    00728   return CBF_NONE;
    00729 }
    00730
    00731 /* --- Aircraft button menu --- */
    00732
    00733 static CallBackFunction ToolbarAirClick(Window *w)
    00734 {
    00735   ToolbarVehicleClick(w, VEH_AIRCRAFT);
    00736   return CBF_NONE;
    00737 }
    00738
    00745 static CallBackFunction MenuClickShowAir(int index)
    00746 {
    00747   ShowVehicleListWindow((CompanyID)index, VEH_AIRCRAFT);
    00748   return CBF_NONE;
    00749 }
    00750
    00751 /* --- Zoom in button --- */
    00752
    00753 static CallBackFunction ToolbarZoomInClick(Window *w)
    00754 {
    00755   if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) {
    00756     w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)WID_TE_ZOOM_IN : (byte)WID_TN_ZOOM_IN);
    00757     SndPlayFx(SND_15_BEEP);
    00758   }
    00759   return CBF_NONE;
    00760 }
    00761
    00762 /* --- Zoom out button --- */
    00763
    00764 static CallBackFunction ToolbarZoomOutClick(Window *w)
    00765 {
    00766   if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) {
    00767     w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)WID_TE_ZOOM_OUT : (byte)WID_TN_ZOOM_OUT);
    00768     SndPlayFx(SND_15_BEEP);
    00769   }
    00770   return CBF_NONE;
    00771 }
    00772
    00773 /* --- Rail button menu --- */
    00774
    00775 static CallBackFunction ToolbarBuildRailClick(Window *w)
    00776 {
    00777   ShowDropDownList(w, GetRailTypeDropDownList(), _last_built_railtype, WID_TN_RAILS, 140, true, true);
    00778   SndPlayFx(SND_15_BEEP);
    00779   return CBF_NONE;
    00780 }
    00781
    00788 static CallBackFunction MenuClickBuildRail(int index)
    00789 {
    00790   _last_built_railtype = (RailType)index;
    00791   ShowBuildRailToolbar(_last_built_railtype);
    00792   return CBF_NONE;
    00793 }
    00794
    00795 /* --- Road button menu --- */
    00796
    00797 static CallBackFunction ToolbarBuildRoadClick(Window *w)
    00798 {
    00799   const Company *c = Company::Get(_local_company);
    00800   DropDownList *list = new DropDownList();
    00801
    00802   /* Road is always visible and available. */
    00803   list->push_back(new DropDownListStringItem(STR_ROAD_MENU_ROAD_CONSTRUCTION, ROADTYPE_ROAD, false));
    00804
    00805   /* Tram is only visible when there will be a tram, and available when that has been introduced. */
    00806   Engine *e;
    00807   FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
    00808     if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue;
    00809     if (!HasBit(e->info.misc_flags, EF_ROAD_TRAM)) continue;
    00810
    00811     list->push_back(new DropDownListStringItem(STR_ROAD_MENU_TRAM_CONSTRUCTION, ROADTYPE_TRAM, !HasBit(c->avail_roadtypes, ROADTYPE_TRAM)));
    00812     break;
    00813   }
    00814   ShowDropDownList(w, list, _last_built_roadtype, WID_TN_ROADS, 140, true, true);
    00815   SndPlayFx(SND_15_BEEP);
    00816   return CBF_NONE;
    00817 }
    00818
    00825 static CallBackFunction MenuClickBuildRoad(int index)
    00826 {
    00827   _last_built_roadtype = (RoadType)index;
    00828   ShowBuildRoadToolbar(_last_built_roadtype);
    00829   return CBF_NONE;
    00830 }
    00831
    00832 /* --- Water button menu --- */
    00833
    00834 static CallBackFunction ToolbarBuildWaterClick(Window *w)
    00835 {
    00836   PopupMainToolbMenu(w, WID_TN_WATER, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 1);
    00837   return CBF_NONE;
    00838 }
    00839
    00846 static CallBackFunction MenuClickBuildWater(int index)
    00847 {
    00848   ShowBuildDocksToolbar();
    00849   return CBF_NONE;
    00850 }
    00851
    00852 /* --- Airport button menu --- */
    00853
    00854 static CallBackFunction ToolbarBuildAirClick(Window *w)
    00855 {
    00856   PopupMainToolbMenu(w, WID_TN_AIR, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 1);
    00857   return CBF_NONE;
    00858 }
    00859
    00866 static CallBackFunction MenuClickBuildAir(int index)
    00867 {
    00868   ShowBuildAirToolbar();
    00869   return CBF_NONE;
    00870 }
    00871
    00872 /* --- Forest button menu --- */
    00873
    00874 static CallBackFunction ToolbarForestClick(Window *w)
    00875 {
    00876   PopupMainToolbMenu(w, WID_TN_LANDSCAPE, STR_LANDSCAPING_MENU_LANDSCAPING, 3);
    00877   return CBF_NONE;
    00878 }
    00879
    00886 static CallBackFunction MenuClickForest(int index)
    00887 {
    00888   switch (index) {
    00889     case 0: ShowTerraformToolbar();  break;
    00890     case 1: ShowBuildTreesToolbar(); break;
    00891     case 2: return SelectSignTool();
    00892   }
    00893   return CBF_NONE;
    00894 }
    00895
    00896 /* --- Music button menu --- */
    00897
    00898 static CallBackFunction ToolbarMusicClick(Window *w)
    00899 {
    00900   PopupMainToolbMenu(w, WID_TN_MUSIC_SOUND, STR_TOOLBAR_SOUND_MUSIC, 1);
    00901   return CBF_NONE;
    00902 }
    00903
    00910 static CallBackFunction MenuClickMusicWindow(int index)
    00911 {
    00912   ShowMusicWindow();
    00913   return CBF_NONE;
    00914 }
    00915
    00916 /* --- Newspaper button menu --- */
    00917
    00918 static CallBackFunction ToolbarNewspaperClick(Window *w)
    00919 {
    00920   PopupMainToolbMenu(w, WID_TN_MESSAGES, STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT, 3);
    00921   return CBF_NONE;
    00922 }
    00923
    00930 static CallBackFunction MenuClickNewspaper(int index)
    00931 {
    00932   switch (index) {
    00933     case 0: ShowLastNewsMessage(); break;
    00934     case 1: ShowMessageOptions();  break;
    00935     case 2: ShowMessageHistory();  break;
    00936   }
    00937   return CBF_NONE;
    00938 }
    00939
    00940 /* --- Help button menu --- */
    00941
    00942 static CallBackFunction PlaceLandBlockInfo()
    00943 {
    00944   if (_cursor.sprite == SPR_CURSOR_QUERY) {
    00945     ResetObjectToPlace();
    00946     return CBF_NONE;
    00947   } else {
    00948     SetObjectToPlace(SPR_CURSOR_QUERY, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0);
    00949     return CBF_PLACE_LANDINFO;
    00950   }
    00951 }
    00952
    00953 static CallBackFunction ToolbarHelpClick(Window *w)
    00954 {
    00955   PopupMainToolbMenu(w, WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 12 : 9);
    00956   return CBF_NONE;
    00957 }
    00958
    00959 static void MenuClickSmallScreenshot()
    00960 {
    00961   MakeScreenshot(SC_VIEWPORT, NULL);
    00962 }
    00963
    00964 static void MenuClickZoomedInScreenshot()
    00965 {
    00966   MakeScreenshot(SC_ZOOMEDIN, NULL);
    00967 }
    00968
    00969 static void MenuClickDefaultZoomScreenshot()
    00970 {
    00971   MakeScreenshot(SC_DEFAULTZOOM, NULL);
    00972 }
    00973
    00974 static void MenuClickWorldScreenshot()
    00975 {
    00976   MakeScreenshot(SC_WORLD, NULL);
    00977 }
    00978
    00986 void ToggleBoundingBoxes()
    00987 {
    00988   extern bool _draw_bounding_boxes;
    00989   /* Always allow to toggle them off */
    00990   if (_settings_client.gui.newgrf_developer_tools || _draw_bounding_boxes) {
    00991     _draw_bounding_boxes = !_draw_bounding_boxes;
    00992     MarkWholeScreenDirty();
    00993   }
    00994 }
    00995
    01003 void ToggleDirtyBlocks()
    01004 {
    01005   extern bool _draw_dirty_blocks;
    01006   /* Always allow to toggle them off */
    01007   if (_settings_client.gui.newgrf_developer_tools || _draw_dirty_blocks) {
    01008     _draw_dirty_blocks = !_draw_dirty_blocks;
    01009     MarkWholeScreenDirty();
    01010   }
    01011 }
    01012
    01018 static CallBackFunction MenuClickHelp(int index)
    01019 {
    01020   switch (index) {
    01021     case  0: return PlaceLandBlockInfo();
    01022     case  2: IConsoleSwitch();                 break;
    01023     case  3: ShowAIDebugWindow();              break;
    01024     case  4: MenuClickSmallScreenshot();       break;
    01025     case  5: MenuClickZoomedInScreenshot();    break;
    01026     case  6: MenuClickDefaultZoomScreenshot(); break;
    01027     case  7: MenuClickWorldScreenshot();       break;
    01028     case  8: ShowAboutWindow();                break;
    01029     case  9: ShowSpriteAlignerWindow();        break;
    01030     case 10: ToggleBoundingBoxes();            break;
    01031     case 11: ToggleDirtyBlocks();              break;
    01032   }
    01033   return CBF_NONE;
    01034 }
    01035
    01036 /* --- Switch toolbar button --- */
    01037
    01038 static CallBackFunction ToolbarSwitchClick(Window *w)
    01039 {
    01040   if (_toolbar_mode != TB_LOWER) {
    01041     _toolbar_mode = TB_LOWER;
    01042   } else {
    01043     _toolbar_mode = TB_UPPER;
    01044   }
    01045
    01046   w->ReInit();
    01047   w->SetWidgetLoweredState(WID_TN_SWITCH_BAR, _toolbar_mode == TB_LOWER);
    01048   SndPlayFx(SND_15_BEEP);
    01049   return CBF_NONE;
    01050 }
    01051
    01052 /* --- Scenario editor specific handlers. */
    01053
    01057 static CallBackFunction ToolbarScenDatePanel(Window *w)
    01058 {
    01059   SetDParam(0, _settings_game.game_creation.starting_year);
    01060   ShowQueryString(STR_JUST_INT, STR_MAPGEN_START_DATE_QUERY_CAPT, 8, w, CS_NUMERAL, QSF_ENABLE_DEFAULT);
    01061   _left_button_clicked = false;
    01062   return CBF_NONE;
    01063 }
    01064
    01065 static CallBackFunction ToolbarScenDateBackward(Window *w)
    01066 {
    01067   /* don't allow too fast scrolling */
    01068   if (!(w->flags & WF_TIMEOUT) || w->timeout_timer <= 1) {
    01069     w->HandleButtonClick(WID_TE_DATE_BACKWARD);
    01070     w->SetDirty();
    01071
    01072     _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year - 1, MIN_YEAR, MAX_YEAR);
    01073     SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
    01074   }
    01075   _left_button_clicked = false;
    01076   return CBF_NONE;
    01077 }
    01078
    01079 static CallBackFunction ToolbarScenDateForward(Window *w)
    01080 {
    01081   /* don't allow too fast scrolling */
    01082   if (!(w->flags & WF_TIMEOUT) || w->timeout_timer <= 1) {
    01083     w->HandleButtonClick(WID_TE_DATE_FORWARD);
    01084     w->SetDirty();
    01085
    01086     _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year + 1, MIN_YEAR, MAX_YEAR);
    01087     SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
    01088   }
    01089   _left_button_clicked = false;
    01090   return CBF_NONE;
    01091 }
    01092
    01093 static CallBackFunction ToolbarScenGenLand(Window *w)
    01094 {
    01095   w->HandleButtonClick(WID_TE_LAND_GENERATE);
    01096   SndPlayFx(SND_15_BEEP);
    01097
    01098   ShowEditorTerraformToolbar();
    01099   return CBF_NONE;
    01100 }
    01101
    01102
    01103 static CallBackFunction ToolbarScenGenTown(Window *w)
    01104 {
    01105   w->HandleButtonClick(WID_TE_TOWN_GENERATE);
    01106   SndPlayFx(SND_15_BEEP);
    01107   ShowFoundTownWindow();
    01108   return CBF_NONE;
    01109 }
    01110
    01111 static CallBackFunction ToolbarScenGenIndustry(Window *w)
    01112 {
    01113   w->HandleButtonClick(WID_TE_INDUSTRY);
    01114   SndPlayFx(SND_15_BEEP);
    01115   ShowBuildIndustryWindow();
    01116   return CBF_NONE;
    01117 }
    01118
    01119 static CallBackFunction ToolbarScenBuildRoad(Window *w)
    01120 {
    01121   w->HandleButtonClick(WID_TE_ROADS);
    01122   SndPlayFx(SND_15_BEEP);
    01123   ShowBuildRoadScenToolbar();
    01124   return CBF_NONE;
    01125 }
    01126
    01127 static CallBackFunction ToolbarScenBuildDocks(Window *w)
    01128 {
    01129   w->HandleButtonClick(WID_TE_WATER);
    01130   SndPlayFx(SND_15_BEEP);
    01131   ShowBuildDocksScenToolbar();
    01132   return CBF_NONE;
    01133 }
    01134
    01135 static CallBackFunction ToolbarScenPlantTrees(Window *w)
    01136 {
    01137   w->HandleButtonClick(WID_TE_TREES);
    01138   SndPlayFx(SND_15_BEEP);
    01139   ShowBuildTreesToolbar();
    01140   return CBF_NONE;
    01141 }
    01142
    01143 static CallBackFunction ToolbarScenPlaceSign(Window *w)
    01144 {
    01145   w->HandleButtonClick(WID_TE_SIGNS);
    01146   SndPlayFx(SND_15_BEEP);
    01147   return SelectSignTool();
    01148 }
    01149
    01150 static CallBackFunction ToolbarBtn_NULL(Window *w)
    01151 {
    01152   return CBF_NONE;
    01153 }
    01154
    01155 typedef CallBackFunction MenuClickedProc(int index);
    01156
    01157 static MenuClickedProc * const _menu_clicked_procs[] = {
    01158   NULL,                 // 0
    01159   NULL,                 // 1
    01160   MenuClickSettings,    // 2
    01161   MenuClickSaveLoad,    // 3
    01162   MenuClickMap,         // 4
    01163   MenuClickTown,        // 5
    01164   MenuClickSubsidies,   // 6
    01165   MenuClickStations,    // 7
    01166   MenuClickFinances,    // 8
    01167   MenuClickCompany,     // 9
    01168   MenuClickGraphs,      // 10
    01169   MenuClickLeague,      // 11
    01170   MenuClickIndustry,    // 12
    01171   MenuClickShowTrains,  // 13
    01172   MenuClickShowRoad,    // 14
    01173   MenuClickShowShips,   // 15
    01174   MenuClickShowAir,     // 16
    01175   MenuClickMap,         // 17
    01176   NULL,                 // 18
    01177   MenuClickBuildRail,   // 19
    01178   MenuClickBuildRoad,   // 20
    01179   MenuClickBuildWater,  // 21
    01180   MenuClickBuildAir,    // 22
    01181   MenuClickForest,      // 23
    01182   MenuClickMusicWindow, // 24
    01183   MenuClickNewspaper,   // 25
    01184   MenuClickHelp,        // 26
    01185 };
    01186
    01187 int16 *_preferred_toolbar_size = NULL;
    01188
    01190 class NWidgetToolbarContainer : public NWidgetContainer {
    01191   bool visible[WID_TN_END];
    01192 protected:
    01193   uint spacers;
    01194
    01195 public:
    01196   NWidgetToolbarContainer() : NWidgetContainer(NWID_HORIZONTAL)
    01197   {
    01198   }
    01199
    01205   bool IsButton(WidgetType type) const
    01206   {
    01207     return type == WWT_IMGBTN || type == WWT_IMGBTN_2 || type == WWT_PUSHIMGBTN;
    01208   }
    01209
    01210   void SetupSmallestSize(Window *w, bool init_array)
    01211   {
    01212     this->smallest_x = 0; // Biggest child
    01213     this->smallest_y = 0; // Biggest child
    01214     this->fill_x = 1;
    01215     this->fill_y = 0;
    01216     this->resize_x = 1; // We only resize in this direction
    01217     this->resize_y = 0; // We never resize in this direction
    01218     this->spacers = 0;
    01219
    01220     uint nbuttons = 0;
    01221     /* First initialise some variables... */
    01222     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
    01223       child_wid->SetupSmallestSize(w, init_array);
    01224       this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom);
    01225       if (this->IsButton(child_wid->type)) {
    01226         nbuttons++;
    01227         this->smallest_x = max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right);
    01228       } else if (child_wid->type == NWID_SPACER) {
    01229         this->spacers++;
    01230       }
    01231     }
    01232
    01233     /* ... then in a second pass make sure the 'current' heights are set. Won't change ever. */
    01234     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
    01235       child_wid->current_y = this->smallest_y;
    01236       if (!this->IsButton(child_wid->type)) {
    01237         child_wid->current_x = child_wid->smallest_x;
    01238       }
    01239     }
    01240     *_preferred_toolbar_size = nbuttons * this->smallest_x;
    01241   }
    01242
    01243   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl)
    01244   {
    01245     assert(given_width >= this->smallest_x && given_height >= this->smallest_y);
    01246
    01247     this->pos_x = x;
    01248     this->pos_y = y;
    01249     this->current_x = given_width;
    01250     this->current_y = given_height;
    01251
    01252     /* Figure out what are the visible buttons */
    01253     memset(this->visible, 0, sizeof(this->visible));
    01254     uint arrangable_count, button_count, spacer_count;
    01255     const byte *arrangement = GetButtonArrangement(given_width, arrangable_count, button_count, spacer_count);
    01256     for (uint i = 0; i < arrangable_count; i++) {
    01257       this->visible[arrangement[i]] = true;
    01258     }
    01259
    01260     /* Create us ourselves a quick lookup table */
    01261     NWidgetBase *widgets[WID_TN_END];
    01262     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
    01263       if (child_wid->type == NWID_SPACER) continue;
    01264       widgets[((NWidgetCore*)child_wid)->index] = child_wid;
    01265     }
    01266
    01267     /* Now assign the widgets to their rightful place */
    01268     uint position = 0; // Place to put next child relative to origin of the container.
    01269     uint spacer_space = max(0, (int)given_width - (int)(button_count * this->smallest_x)); // Remaining spacing for 'spacer' widgets
    01270     uint button_space = given_width - spacer_space; // Remaining spacing for the buttons
    01271     uint spacer_i = 0;
    01272     uint button_i = 0;
    01273
    01274     /* Index into the arrangement indices. The macro lastof cannot be used here! */
    01275     const byte *cur_wid = rtl ? &arrangement[arrangable_count - 1] : arrangement;
    01276     for (uint i = 0; i < arrangable_count; i++) {
    01277       NWidgetBase *child_wid = widgets[*cur_wid];
    01278       /* If we have to give space to the spacers, do that */
    01279       if (spacer_space != 0) {
    01280         NWidgetBase *possible_spacer = rtl ? child_wid->next : child_wid->prev;
    01281         if (possible_spacer != NULL && possible_spacer->type == NWID_SPACER) {
    01282           uint add = spacer_space / (spacer_count - spacer_i);
    01283           position += add;
    01284           spacer_space -= add;
    01285           spacer_i++;
    01286         }
    01287       }
    01288
    01289       /* Buttons can be scaled, the others not. */
    01290       if (this->IsButton(child_wid->type)) {
    01291         child_wid->current_x = button_space / (button_count - button_i);
    01292         button_space -= child_wid->current_x;
    01293         button_i++;
    01294       }
    01295       child_wid->AssignSizePosition(sizing, x + position, y, child_wid->current_x, this->current_y, rtl);
    01296       position += child_wid->current_x;
    01297
    01298       if (rtl) {
    01299         cur_wid--;
    01300       } else {
    01301         cur_wid++;
    01302       }
    01303     }
    01304   }
    01305
    01306   /* virtual */ void Draw(const Window *w)
    01307   {
    01308     /* Draw brown-red toolbar bg. */
    01309     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);
    01310     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);
    01311
    01312     bool rtl = _current_text_dir == TD_RTL;
    01313     for (NWidgetBase *child_wid = rtl ? this->tail : this->head; child_wid != NULL; child_wid = rtl ? child_wid->prev : child_wid->next) {
    01314       if (child_wid->type == NWID_SPACER) continue;
    01315       if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
    01316
    01317       child_wid->Draw(w);
    01318     }
    01319   }
    01320
    01321   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y)
    01322   {
    01323     if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL;
    01324
    01325     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
    01326       if (child_wid->type == NWID_SPACER) continue;
    01327       if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
    01328
    01329       NWidgetCore *nwid = child_wid->GetWidgetFromPos(x, y);
    01330       if (nwid != NULL) return nwid;
    01331     }
    01332     return NULL;
    01333   }
    01334
    01343   virtual const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const = 0;
    01344 };
    01345
    01347 class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
    01348   /* virtual */ const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
    01349   {
    01350     static const uint SMALLEST_ARRANGEMENT = 14;
    01351     static const uint BIGGEST_ARRANGEMENT  = 19;
    01352     static const byte arrange14[] = {
    01353       0,  1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 27,
    01354       2,  3,  4,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 27,
    01355     };
    01356     static const byte arrange15[] = {
    01357       0,  1,  4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
    01358       0,  2,  4,  3,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 27,
    01359     };
    01360     static const byte arrange16[] = {
    01361       0,  1,  2,  4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
    01362       0,  1,  3,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 17, 18, 27,
    01363     };
    01364     static const byte arrange17[] = {
    01365       0,  1,  2,  4,  6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
    01366       0,  1,  3,  4,  6,  5,  7,  8,  9, 10, 12, 24, 25, 26, 17, 18, 27,
    01367     };
    01368     static const byte arrange18[] = {
    01369       0,  1,  2,  4,  5,  6,  7,  8,  9, 12, 19, 20, 21, 22, 23, 17, 18, 27,
    01370       0,  1,  3,  4,  5,  6,  7, 10, 13, 14, 15, 16, 24, 25, 26, 17, 18, 27,
    01371     };
    01372     static const byte arrange19[] = {
    01373       0,  1,  2,  4,  5,  6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 27,
    01374       0,  1,  3,  4,  7,  8,  9, 10, 12, 25, 19, 20, 21, 22, 23, 26, 17, 18, 27,
    01375     };
    01376     static const byte arrange_all[] = {
    01377       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,
    01378     };
    01379
    01380     /* If at least BIGGEST_ARRANGEMENT fit, just spread all the buttons nicely */
    01381     uint full_buttons = max(CeilDiv(width, this->smallest_x), SMALLEST_ARRANGEMENT);
    01382     if (full_buttons > BIGGEST_ARRANGEMENT) {
    01383       button_count = arrangable_count = lengthof(arrange_all);
    01384       spacer_count = this->spacers;
    01385       return arrange_all;
    01386     }
    01387
    01388     /* Introduce the split toolbar */
    01389     static const byte * const arrangements[] = { arrange14, arrange15, arrange16, arrange17, arrange18, arrange19 };
    01390
    01391     button_count = arrangable_count = full_buttons;
    01392     spacer_count = this->spacers;
    01393     return arrangements[full_buttons - SMALLEST_ARRANGEMENT] + ((_toolbar_mode == TB_LOWER) ? full_buttons : 0);
    01394   }
    01395 };
    01396
    01398 class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer {
    01399   uint panel_widths[2];
    01400
    01401   void SetupSmallestSize(Window *w, bool init_array)
    01402   {
    01403     this->NWidgetToolbarContainer::SetupSmallestSize(w, init_array);
    01404
    01405     /* Find the size of panel_widths */
    01406     uint i = 0;
    01407     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
    01408       if (child_wid->type == NWID_SPACER || this->IsButton(child_wid->type)) continue;
    01409
    01410       assert(i < lengthof(this->panel_widths));
    01411       this->panel_widths[i++] = child_wid->current_x;
    01412       *_preferred_toolbar_size += child_wid->current_x;
    01413     }
    01414   }
    01415
    01416   /* virtual */ const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
    01417   {
    01418     static const byte arrange_all[] = {
    01419       0, 1, 2, 3, 4, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24, 26,
    01420     };
    01421     static const byte arrange_nopanel[] = {
    01422       0, 1, 2, 3, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24, 26,
    01423     };
    01424     static const byte arrange_switch[] = {
    01425       18,  8, 11, 12, 13, 14, 15, 16, 17, 27,
    01426        0,  1,  2,  3, 18,  9, 10, 24, 26, 27,
    01427     };
    01428
    01429     /* If we can place all buttons *and* the panels, show them. */
    01430     uint min_full_width = (lengthof(arrange_all) - lengthof(this->panel_widths)) * this->smallest_x + this->panel_widths[0] + this->panel_widths[1];
    01431     if (width >= min_full_width) {
    01432       width -= this->panel_widths[0] + this->panel_widths[1];
    01433       arrangable_count = lengthof(arrange_all);
    01434       button_count = arrangable_count - 2;
    01435       spacer_count = this->spacers;
    01436       return arrange_all;
    01437     }
    01438
    01439     /* 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 */
    01440     uint min_small_width = (lengthof(arrange_switch) - lengthof(this->panel_widths)) * this->smallest_x / 2 + this->panel_widths[1];
    01441     if (width > min_small_width) {
    01442       width -= this->panel_widths[1];
    01443       arrangable_count = lengthof(arrange_nopanel);
    01444       button_count = arrangable_count - 1;
    01445       spacer_count = this->spacers - 1;
    01446       return arrange_nopanel;
    01447     }
    01448
    01449     /* Split toolbar */
    01450     width -= this->panel_widths[1];
    01451     arrangable_count = lengthof(arrange_switch) / 2;
    01452     button_count = arrangable_count - 1;
    01453     spacer_count = 0;
    01454     return arrange_switch + ((_toolbar_mode == TB_LOWER) ? arrangable_count : 0);
    01455   }
    01456 };
    01457
    01458 /* --- Toolbar handling for the 'normal' case */
    01459
    01460 typedef CallBackFunction ToolbarButtonProc(Window *w);
    01461
    01462 static ToolbarButtonProc * const _toolbar_button_procs[] = {
    01463   ToolbarPauseClick,
    01464   ToolbarFastForwardClick,
    01465   ToolbarOptionsClick,
    01466   ToolbarSaveClick,
    01467   ToolbarMapClick,
    01468   ToolbarTownClick,
    01469   ToolbarSubsidiesClick,
    01470   ToolbarStationsClick,
    01471   ToolbarFinancesClick,
    01472   ToolbarCompaniesClick,
    01473   ToolbarGraphsClick,
    01474   ToolbarLeagueClick,
    01475   ToolbarIndustryClick,
    01476   ToolbarTrainClick,
    01477   ToolbarRoadClick,
    01478   ToolbarShipClick,
    01479   ToolbarAirClick,
    01480   ToolbarZoomInClick,
    01481   ToolbarZoomOutClick,
    01482   ToolbarBuildRailClick,
    01483   ToolbarBuildRoadClick,
    01484   ToolbarBuildWaterClick,
    01485   ToolbarBuildAirClick,
    01486   ToolbarForestClick,
    01487   ToolbarMusicClick,
    01488   ToolbarNewspaperClick,
    01489   ToolbarHelpClick,
    01490   ToolbarSwitchClick,
    01491 };
    01492
    01493 enum MainToolbarHotkeys {
    01494   MTHK_PAUSE,
    01495   MTHK_FASTFORWARD,
    01496   MTHK_SETTINGS,
    01497   MTHK_SAVEGAME,
    01498   MTHK_LOADGAME,
    01499   MTHK_SMALLMAP,
    01500   MTHK_TOWNDIRECTORY,
    01501   MTHK_SUBSIDIES,
    01502   MTHK_STATIONS,
    01503   MTHK_FINANCES,
    01504   MTHK_COMPANIES,
    01505   MTHK_GRAPHS,
    01506   MTHK_LEAGUE,
    01507   MTHK_INDUSTRIES,
    01508   MTHK_TRAIN_LIST,
    01509   MTHK_ROADVEH_LIST,
    01510   MTHK_SHIP_LIST,
    01511   MTHK_AIRCRAFT_LIST,
    01512   MTHK_ZOOM_IN,
    01513   MTHK_ZOOM_OUT,
    01514   MTHK_BUILD_RAIL,
    01515   MTHK_BUILD_ROAD,
    01516   MTHK_BUILD_DOCKS,
    01517   MTHK_BUILD_AIRPORT,
    01518   MTHK_BUILD_TREES,
    01519   MTHK_MUSIC,
    01520   MTHK_AI_DEBUG,
    01521   MTHK_SMALL_SCREENSHOT,
    01522   MTHK_ZOOMEDIN_SCREENSHOT,
    01523   MTHK_DEFAULTZOOM_SCREENSHOT,
    01524   MTHK_GIANT_SCREENSHOT,
    01525   MTHK_CHEATS,
    01526   MTHK_TERRAFORM,
    01527   MTHK_EXTRA_VIEWPORT,
    01528   MTHK_CLIENT_LIST,
    01529   MTHK_SIGN_LIST,
    01530 };
    01531
    01533 struct MainToolbarWindow : Window {
    01534   CallBackFunction last_started_action;
    01535
    01536   MainToolbarWindow(const WindowDesc *desc) : Window()
    01537   {
    01538     this->InitNested(desc, 0);
    01539
    01540     this->last_started_action = CBF_NONE;
    01541     CLRBITS(this->flags, WF_WHITE_BORDER);
    01542     this->SetWidgetDisabledState(WID_TN_PAUSE, _networking && !_network_server); // if not server, disable pause button
    01543     this->SetWidgetDisabledState(WID_TN_FAST_FORWARD, _networking); // if networking, disable fast-forward button
    01544     PositionMainToolbar(this);
    01545     DoZoomInOutWindow(ZOOM_NONE, this);
    01546   }
    01547
    01548   virtual void OnPaint()
    01549   {
    01550     /* If spectator, disable all construction buttons
    01551      * ie : Build road, rail, ships, airports and landscaping
    01552      * Since enabled state is the default, just disable when needed */
    01553     this->SetWidgetsDisabledState(_local_company == COMPANY_SPECTATOR, WID_TN_RAILS, WID_TN_ROADS, WID_TN_WATER, WID_TN_AIR, WID_TN_LANDSCAPE, WIDGET_LIST_END);
    01554     /* disable company list drop downs, if there are no companies */
    01555     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);
    01556
    01557     this->SetWidgetDisabledState(WID_TN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN));
    01558     this->SetWidgetDisabledState(WID_TN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT));
    01559
    01560     this->DrawWidgets();
    01561   }
    01562
    01563   virtual void OnClick(Point pt, int widget, int click_count)
    01564   {
    01565     if (_game_mode != GM_MENU && !this->IsWidgetDisabled(widget)) _toolbar_button_procs[widget](this);
    01566   }
    01567
    01568   virtual void OnDropdownSelect(int widget, int index)
    01569   {
    01570     CallBackFunction cbf = _menu_clicked_procs[widget](index);
    01571     if (cbf != CBF_NONE) this->last_started_action = cbf;
    01572   }
    01573
    01574   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
    01575   {
    01576     switch (CheckHotkeyMatch(maintoolbar_hotkeys, keycode, this)) {
    01577       case MTHK_PAUSE: ToolbarPauseClick(this); break;
    01578       case MTHK_FASTFORWARD: ToolbarFastForwardClick(this); break;
    01579       case MTHK_SETTINGS: ShowGameOptions(); break;
    01580       case MTHK_SAVEGAME: MenuClickSaveLoad(); break;
    01581       case MTHK_LOADGAME: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
    01582       case MTHK_SMALLMAP: ShowSmallMap(); break;
    01583       case MTHK_TOWNDIRECTORY: ShowTownDirectory(); break;
    01584       case MTHK_SUBSIDIES: ShowSubsidiesList(); break;
    01585       case MTHK_STATIONS: ShowCompanyStations(_local_company); break;
    01586       case MTHK_FINANCES: ShowCompanyFinances(_local_company); break;
    01587       case MTHK_COMPANIES: ShowCompany(_local_company); break;
    01588       case MTHK_GRAPHS: ShowOperatingProfitGraph(); break;
    01589       case MTHK_LEAGUE: ShowCompanyLeagueTable(); break;
    01590       case MTHK_INDUSTRIES: ShowBuildIndustryWindow(); break;
    01591       case MTHK_TRAIN_LIST: ShowVehicleListWindow(_local_company, VEH_TRAIN); break;
    01592       case MTHK_ROADVEH_LIST: ShowVehicleListWindow(_local_company, VEH_ROAD); break;
    01593       case MTHK_SHIP_LIST: ShowVehicleListWindow(_local_company, VEH_SHIP); break;
    01594       case MTHK_AIRCRAFT_LIST: ShowVehicleListWindow(_local_company, VEH_AIRCRAFT); break;
    01595       case MTHK_ZOOM_IN: ToolbarZoomInClick(this); break;
    01596       case MTHK_ZOOM_OUT: ToolbarZoomOutClick(this); break;
    01597       case MTHK_BUILD_RAIL: if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype); break;
    01598       case MTHK_BUILD_ROAD: ShowBuildRoadToolbar(_last_built_roadtype); break;
    01599       case MTHK_BUILD_DOCKS: ShowBuildDocksToolbar(); break;
    01600       case MTHK_BUILD_AIRPORT: if (CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) ShowBuildAirToolbar(); break;
    01601       case MTHK_BUILD_TREES: ShowBuildTreesToolbar(); break;
    01602       case MTHK_MUSIC: ShowMusicWindow(); break;
    01603       case MTHK_AI_DEBUG: ShowAIDebugWindow(); break;
    01604       case MTHK_SMALL_SCREENSHOT: MenuClickSmallScreenshot(); break;
    01605       case MTHK_ZOOMEDIN_SCREENSHOT: MenuClickZoomedInScreenshot(); break;
    01606       case MTHK_DEFAULTZOOM_SCREENSHOT: MenuClickDefaultZoomScreenshot(); break;
    01607       case MTHK_GIANT_SCREENSHOT: MenuClickWorldScreenshot(); break;
    01608       case MTHK_CHEATS: if (!_networking) ShowCheatWindow(); break;
    01609       case MTHK_TERRAFORM: ShowTerraformToolbar(); break;
    01610       case MTHK_EXTRA_VIEWPORT: ShowExtraViewPortWindowForTileUnderCursor(); break;
    01611 #ifdef ENABLE_NETWORK
    01612       case MTHK_CLIENT_LIST: if (_networking) ShowClientList(); break;
    01613 #endif
    01614       case MTHK_SIGN_LIST: ShowSignList(); break;
    01615       default: return ES_NOT_HANDLED;
    01616     }
    01617     return ES_HANDLED;
    01618   }
    01619
    01620   virtual void OnPlaceObject(Point pt, TileIndex tile)
    01621   {
    01622     switch (this->last_started_action) {
    01623       case CBF_PLACE_SIGN:
    01624         PlaceProc_Sign(tile);
    01625         break;
    01626
    01627       case CBF_PLACE_LANDINFO:
    01628         ShowLandInfo(tile);
    01629         break;
    01630
    01631       default: NOT_REACHED();
    01632     }
    01633   }
    01634
    01635   virtual void OnTick()
    01636   {
    01637     if (this->IsWidgetLowered(WID_TN_PAUSE) != !!_pause_mode) {
    01638       this->ToggleWidgetLoweredState(WID_TN_PAUSE);
    01639       this->SetWidgetDirty(WID_TN_PAUSE);
    01640     }
    01641
    01642     if (this->IsWidgetLowered(WID_TN_FAST_FORWARD) != !!_fast_forward) {
    01643       this->ToggleWidgetLoweredState(WID_TN_FAST_FORWARD);
    01644       this->SetWidgetDirty(WID_TN_FAST_FORWARD);
    01645     }
    01646   }
    01647
    01648   virtual void OnTimeout()
    01649   {
    01650     /* We do not want to automatically raise the pause, fast forward and
    01651      * switchbar buttons; they have to stay down when pressed etc. */
    01652     for (uint i = WID_TN_SETTINGS; i < WID_TN_SWITCH_BAR; i++) {
    01653       if (this->IsWidgetLowered(i)) {
    01654         this->RaiseWidget(i);
    01655         this->SetWidgetDirty(i);
    01656       }
    01657     }
    01658   }
    01659
    01665   virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
    01666   {
    01667     if (!gui_scope) return;
    01668     if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TN_ZOOM_IN, WID_TN_ZOOM_OUT);
    01669   }
    01670
    01671   static Hotkey<MainToolbarWindow> maintoolbar_hotkeys[];
    01672 };
    01673
    01674 const uint16 _maintoolbar_pause_keys[] = {WKC_F1, WKC_PAUSE, 0};
    01675 const uint16 _maintoolbar_zoomin_keys[] = {WKC_NUM_PLUS, WKC_EQUALS, WKC_SHIFT | WKC_EQUALS, WKC_SHIFT | WKC_F5, 0};
    01676 const uint16 _maintoolbar_zoomout_keys[] = {WKC_NUM_MINUS, WKC_MINUS, WKC_SHIFT | WKC_MINUS, WKC_SHIFT | WKC_F6, 0};
    01677 const uint16 _maintoolbar_smallmap_keys[] = {WKC_F4, 'M', 0};
    01678
    01679 Hotkey<MainToolbarWindow> MainToolbarWindow::maintoolbar_hotkeys[] = {
    01680   Hotkey<MainToolbarWindow>(_maintoolbar_pause_keys, "pause", MTHK_PAUSE),
    01681   Hotkey<MainToolbarWindow>((uint16)0, "fastforward", MTHK_FASTFORWARD),
    01682   Hotkey<MainToolbarWindow>(WKC_F2, "settings", MTHK_SETTINGS),
    01683   Hotkey<MainToolbarWindow>(WKC_F3, "saveload", MTHK_SAVEGAME),
    01684   Hotkey<MainToolbarWindow>((uint16)0, "load_game", MTHK_LOADGAME),
    01685   Hotkey<MainToolbarWindow>(_maintoolbar_smallmap_keys, "smallmap", MTHK_SMALLMAP),
    01686   Hotkey<MainToolbarWindow>(WKC_F5, "town_list", MTHK_TOWNDIRECTORY),
    01687   Hotkey<MainToolbarWindow>(WKC_F6, "subsidies", MTHK_SUBSIDIES),
    01688   Hotkey<MainToolbarWindow>(WKC_F7, "station_list", MTHK_STATIONS),
    01689   Hotkey<MainToolbarWindow>(WKC_F8, "finances", MTHK_FINANCES),
    01690   Hotkey<MainToolbarWindow>(WKC_F9, "companies", MTHK_COMPANIES),
    01691   Hotkey<MainToolbarWindow>(WKC_F10, "graphs", MTHK_GRAPHS),
    01692   Hotkey<MainToolbarWindow>(WKC_F11, "league", MTHK_LEAGUE),
    01693   Hotkey<MainToolbarWindow>(WKC_F12, "industry_list", MTHK_INDUSTRIES),
    01694   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F1, "train_list", MTHK_TRAIN_LIST),
    01695   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F2, "roadveh_list", MTHK_ROADVEH_LIST),
    01696   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F3, "ship_list", MTHK_SHIP_LIST),
    01697   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F4, "aircraft_list", MTHK_AIRCRAFT_LIST),
    01698   Hotkey<MainToolbarWindow>(_maintoolbar_zoomin_keys, "zoomin", MTHK_ZOOM_IN),
    01699   Hotkey<MainToolbarWindow>(_maintoolbar_zoomout_keys, "zoomout", MTHK_ZOOM_OUT),
    01700   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F7, "build_rail", MTHK_BUILD_RAIL),
    01701   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F8, "build_road", MTHK_BUILD_ROAD),
    01702   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F9, "build_docks", MTHK_BUILD_DOCKS),
    01703   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F10, "build_airport", MTHK_BUILD_AIRPORT),
    01704   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F11, "build_trees", MTHK_BUILD_TREES),
    01705   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F12, "music", MTHK_MUSIC),
    01706   Hotkey<MainToolbarWindow>((uint16)0, "ai_debug", MTHK_AI_DEBUG),
    01707   Hotkey<MainToolbarWindow>(WKC_CTRL  | 'S', "small_screenshot", MTHK_SMALL_SCREENSHOT),
    01708   Hotkey<MainToolbarWindow>(WKC_CTRL  | 'P', "zoomedin_screenshot", MTHK_ZOOMEDIN_SCREENSHOT),
    01709   Hotkey<MainToolbarWindow>(WKC_CTRL  | 'D', "defaultzoom_screenshot", MTHK_DEFAULTZOOM_SCREENSHOT),
    01710   Hotkey<MainToolbarWindow>((uint16)0, "giant_screenshot", MTHK_GIANT_SCREENSHOT),
    01711   Hotkey<MainToolbarWindow>(WKC_CTRL | WKC_ALT | 'C', "cheats", MTHK_CHEATS),
    01712   Hotkey<MainToolbarWindow>('L', "terraform", MTHK_TERRAFORM),
    01713   Hotkey<MainToolbarWindow>('V', "extra_viewport", MTHK_EXTRA_VIEWPORT),
    01714 #ifdef ENABLE_NETWORK
    01715   Hotkey<MainToolbarWindow>((uint16)0, "client_list", MTHK_CLIENT_LIST),
    01716 #endif
    01717   Hotkey<MainToolbarWindow>((uint16)0, "sign_list", MTHK_SIGN_LIST),
    01718   HOTKEY_LIST_END(MainToolbarWindow)
    01719 };
    01720 Hotkey<MainToolbarWindow> *_maintoolbar_hotkeys = MainToolbarWindow::maintoolbar_hotkeys;
    01721
    01722 static NWidgetBase *MakeMainToolbar(int *biggest_index)
    01723 {
    01725   static const SpriteID toolbar_button_sprites[] = {
    01726     SPR_IMG_PAUSE,           // WID_TN_PAUSE
    01727     SPR_IMG_FASTFORWARD,     // WID_TN_FAST_FORWARD
    01728     SPR_IMG_SETTINGS,        // WID_TN_SETTINGS
    01729     SPR_IMG_SAVE,            // WID_TN_SAVE
    01730     SPR_IMG_SMALLMAP,        // WID_TN_SMALL_MAP
    01731     SPR_IMG_TOWN,            // WID_TN_TOWNS
    01732     SPR_IMG_SUBSIDIES,       // WID_TN_SUBSIDIES
    01733     SPR_IMG_COMPANY_LIST,    // WID_TN_STATIONS
    01734     SPR_IMG_COMPANY_FINANCE, // WID_TN_FINANCES
    01735     SPR_IMG_COMPANY_GENERAL, // WID_TN_COMPANIES
    01736     SPR_IMG_GRAPHS,          // WID_TN_GRAPHS
    01737     SPR_IMG_COMPANY_LEAGUE,  // WID_TN_LEAGUE
    01738     SPR_IMG_INDUSTRY,        // WID_TN_INDUSTRIES
    01739     SPR_IMG_TRAINLIST,       // WID_TN_TRAINS
    01740     SPR_IMG_TRUCKLIST,       // WID_TN_ROADVEHS
    01741     SPR_IMG_SHIPLIST,        // WID_TN_SHIPS
    01742     SPR_IMG_AIRPLANESLIST,   // WID_TN_AIRCRAFT
    01743     SPR_IMG_ZOOMIN,          // WID_TN_ZOOMIN
    01744     SPR_IMG_ZOOMOUT,         // WID_TN_ZOOMOUT
    01745     SPR_IMG_BUILDRAIL,       // WID_TN_RAILS
    01746     SPR_IMG_BUILDROAD,       // WID_TN_ROADS
    01747     SPR_IMG_BUILDWATER,      // WID_TN_WATER
    01748     SPR_IMG_BUILDAIR,        // WID_TN_AIR
    01749     SPR_IMG_LANDSCAPING,     // WID_TN_LANDSCAPE
    01750     SPR_IMG_MUSIC,           // WID_TN_MUSIC_SOUND
    01751     SPR_IMG_MESSAGES,        // WID_TN_MESSAGES
    01752     SPR_IMG_QUERY,           // WID_TN_HELP
    01753     SPR_IMG_SWITCH_TOOLBAR,  // WID_TN_SWITCH_BAR
    01754   };
    01755
    01756   NWidgetMainToolbarContainer *hor = new NWidgetMainToolbarContainer();
    01757   for (uint i = 0; i < WID_TN_END; i++) {
    01758     switch (i) {
    01759       case 4: case 8: case 13: case 17: case 19: case 24: hor->Add(new NWidgetSpacer(0, 0)); break;
    01760     }
    01761     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));
    01762   }
    01763
    01764   *biggest_index = max<int>(*biggest_index, WID_TN_SWITCH_BAR);
    01765   return hor;
    01766 }
    01767
    01768 static const NWidgetPart _nested_toolbar_normal_widgets[] = {
    01769   NWidgetFunction(MakeMainToolbar),
    01770 };
    01771
    01772 static WindowDesc _toolb_normal_desc(
    01773   WDP_MANUAL, 640, 22,
    01774   WC_MAIN_TOOLBAR, WC_NONE,
    01775   WDF_NO_FOCUS,
    01776   _nested_toolbar_normal_widgets, lengthof(_nested_toolbar_normal_widgets)
    01777 );
    01778
    01779
    01780 /* --- Toolbar handling for the scenario editor */
    01781
    01782 static ToolbarButtonProc * const _scen_toolbar_button_procs[] = {
    01783   ToolbarPauseClick,
    01784   ToolbarFastForwardClick,
    01785   ToolbarOptionsClick,
    01786   ToolbarScenSaveOrLoad,
    01787   ToolbarBtn_NULL,
    01788   ToolbarScenDatePanel,
    01789   ToolbarScenDateBackward,
    01790   ToolbarScenDateForward,
    01791   ToolbarScenMapTownDir,
    01792   ToolbarZoomInClick,
    01793   ToolbarZoomOutClick,
    01794   ToolbarScenGenLand,
    01795   ToolbarScenGenTown,
    01796   ToolbarScenGenIndustry,
    01797   ToolbarScenBuildRoad,
    01798   ToolbarScenBuildDocks,
    01799   ToolbarScenPlantTrees,
    01800   ToolbarScenPlaceSign,
    01801   ToolbarBtn_NULL,
    01802   NULL,
    01803   NULL,
    01804   NULL,
    01805   NULL,
    01806   NULL,
    01807   ToolbarMusicClick,
    01808   NULL,
    01809   ToolbarHelpClick,
    01810   ToolbarSwitchClick,
    01811 };
    01812
    01813 enum MainToolbarEditorHotkeys {
    01814   MTEHK_PAUSE,
    01815   MTEHK_FASTFORWARD,
    01816   MTEHK_SETTINGS,
    01817   MTEHK_SAVEGAME,
    01818   MTEHK_GENLAND,
    01819   MTEHK_GENTOWN,
    01820   MTEHK_GENINDUSTRY,
    01821   MTEHK_BUILD_ROAD,
    01822   MTEHK_BUILD_DOCKS,
    01823   MTEHK_BUILD_TREES,
    01824   MTEHK_SIGN,
    01825   MTEHK_MUSIC,
    01826   MTEHK_LANDINFO,
    01827   MTEHK_SMALL_SCREENSHOT,
    01828   MTEHK_ZOOMEDIN_SCREENSHOT,
    01829   MTEHK_DEFAULTZOOM_SCREENSHOT,
    01830   MTEHK_GIANT_SCREENSHOT,
    01831   MTEHK_ZOOM_IN,
    01832   MTEHK_ZOOM_OUT,
    01833   MTEHK_TERRAFORM,
    01834   MTEHK_SMALLMAP,
    01835   MTEHK_EXTRA_VIEWPORT,
    01836 };
    01837
    01838 struct ScenarioEditorToolbarWindow : Window {
    01839   CallBackFunction last_started_action;
    01840
    01841   ScenarioEditorToolbarWindow(const WindowDesc *desc) : Window()
    01842   {
    01843     this->InitNested(desc, 0);
    01844
    01845     this->last_started_action = CBF_NONE;
    01846     CLRBITS(this->flags, WF_WHITE_BORDER);
    01847     PositionMainToolbar(this);
    01848     DoZoomInOutWindow(ZOOM_NONE, this);
    01849   }
    01850
    01851   virtual void OnPaint()
    01852   {
    01853     this->SetWidgetDisabledState(WID_TE_DATE_BACKWARD, _settings_game.game_creation.starting_year <= MIN_YEAR);
    01854     this->SetWidgetDisabledState(WID_TE_DATE_FORWARD, _settings_game.game_creation.starting_year >= MAX_YEAR);
    01855
    01856     this->DrawWidgets();
    01857   }
    01858
    01859   virtual void DrawWidget(const Rect &r, int widget) const
    01860   {
    01861     switch (widget) {
    01862       case WID_TE_DATE:
    01863         SetDParam(0, ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
    01864         DrawString(r.left, r.right, (this->height - FONT_HEIGHT_NORMAL) / 2, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_HOR_CENTER);
    01865         break;
    01866
    01867       case WID_TE_SPACER: {
    01868         int height = r.bottom - r.top;
    01869         if (height > 2 * FONT_HEIGHT_NORMAL) {
    01870           DrawString(r.left, r.right, (height + 1) / 2 - FONT_HEIGHT_NORMAL, STR_SCENEDIT_TOOLBAR_OPENTTD, TC_FROMSTRING, SA_HOR_CENTER);
    01871           DrawString(r.left, r.right, (height + 1) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER);
    01872         } else {
    01873           DrawString(r.left, r.right, (height - FONT_HEIGHT_NORMAL) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER);
    01874         }
    01875         break;
    01876       }
    01877     }
    01878   }
    01879
    01880   virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
    01881   {
    01882     switch (widget) {
    01883       case WID_TE_SPACER:
    01884         size->width = max(GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_OPENTTD).width, GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR).width) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
    01885         break;
    01886
    01887       case WID_TE_DATE:
    01888         SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1));
    01889         *size = GetStringBoundingBox(STR_WHITE_DATE_LONG);
    01890         size->height = max(size->height, GetSpriteSize(SPR_IMG_SAVE).height + WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM);
    01891         break;
    01892     }
    01893   }
    01894
    01895   virtual void OnClick(Point pt, int widget, int click_count)
    01896   {
    01897     if (_game_mode == GM_MENU) return;
    01898     CallBackFunction cbf = _scen_toolbar_button_procs[widget](this);
    01899     if (cbf != CBF_NONE) this->last_started_action = cbf;
    01900   }
    01901
    01902   virtual void OnDropdownSelect(int widget, int index)
    01903   {
    01904     /* The map button is in a different location on the scenario
    01905      * editor toolbar, so we need to adjust for it. */
    01906     if (widget == WID_TE_SMALL_MAP) widget = WID_TN_SMALL_MAP;
    01907     CallBackFunction cbf = _menu_clicked_procs[widget](index);
    01908     if (cbf != CBF_NONE) this->last_started_action = cbf;
    01909     SndPlayFx(SND_15_BEEP);
    01910   }
    01911
    01912   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
    01913   {
    01914     CallBackFunction cbf = CBF_NONE;
    01915     switch (CheckHotkeyMatch(scenedit_maintoolbar_hotkeys, keycode, this)) {
    01916       case MTEHK_PAUSE:                  ToolbarPauseClick(this); break;
    01917       case MTEHK_FASTFORWARD:            ToolbarFastForwardClick(this); break;
    01918       case MTEHK_SETTINGS:               ShowGameOptions(); break;
    01919       case MTEHK_SAVEGAME:               MenuClickSaveLoad(); break;
    01920       case MTEHK_GENLAND:                ToolbarScenGenLand(this); break;
    01921       case MTEHK_GENTOWN:                ToolbarScenGenTown(this); break;
    01922       case MTEHK_GENINDUSTRY:            ToolbarScenGenIndustry(this); break;
    01923       case MTEHK_BUILD_ROAD:             ToolbarScenBuildRoad(this); break;
    01924       case MTEHK_BUILD_DOCKS:            ToolbarScenBuildDocks(this); break;
    01925       case MTEHK_BUILD_TREES:            ToolbarScenPlantTrees(this); break;
    01926       case MTEHK_SIGN:                   cbf = ToolbarScenPlaceSign(this); break;
    01927       case MTEHK_MUSIC:                  ShowMusicWindow(); break;
    01928       case MTEHK_LANDINFO:               cbf = PlaceLandBlockInfo(); break;
    01929       case MTEHK_SMALL_SCREENSHOT:       MenuClickSmallScreenshot(); break;
    01930       case MTEHK_ZOOMEDIN_SCREENSHOT:    MenuClickZoomedInScreenshot(); break;
    01931       case MTEHK_DEFAULTZOOM_SCREENSHOT: MenuClickDefaultZoomScreenshot(); break;
    01932       case MTEHK_GIANT_SCREENSHOT:       MenuClickWorldScreenshot(); break;
    01933       case MTEHK_ZOOM_IN:                ToolbarZoomInClick(this); break;
    01934       case MTEHK_ZOOM_OUT:               ToolbarZoomOutClick(this); break;
    01935       case MTEHK_TERRAFORM:              ShowEditorTerraformToolbar(); break;
    01936       case MTEHK_SMALLMAP:               ShowSmallMap(); break;
    01937       case MTEHK_EXTRA_VIEWPORT:         ShowExtraViewPortWindowForTileUnderCursor(); break;
    01938       default: return ES_NOT_HANDLED;
    01939     }
    01940     if (cbf != CBF_NONE) this->last_started_action = cbf;
    01941     return ES_HANDLED;
    01942   }
    01943
    01944   virtual void OnPlaceObject(Point pt, TileIndex tile)
    01945   {
    01946     switch (this->last_started_action) {
    01947       case CBF_PLACE_SIGN:
    01948         PlaceProc_Sign(tile);
    01949         break;
    01950
    01951       case CBF_PLACE_LANDINFO:
    01952         ShowLandInfo(tile);
    01953         break;
    01954
    01955       default: NOT_REACHED();
    01956     }
    01957   }
    01958
    01959   virtual void OnTimeout()
    01960   {
    01961     this->SetWidgetsLoweredState(false, WID_TE_DATE_BACKWARD, WID_TE_DATE_FORWARD, WIDGET_LIST_END);
    01962     this->SetWidgetDirty(WID_TE_DATE_BACKWARD);
    01963     this->SetWidgetDirty(WID_TE_DATE_FORWARD);
    01964   }
    01965
    01966   virtual void OnTick()
    01967   {
    01968     if (this->IsWidgetLowered(WID_TE_PAUSE) != !!_pause_mode) {
    01969       this->ToggleWidgetLoweredState(WID_TE_PAUSE);
    01970       this->SetDirty();
    01971     }
    01972
    01973     if (this->IsWidgetLowered(WID_TE_FAST_FORWARD) != !!_fast_forward) {
    01974       this->ToggleWidgetLoweredState(WID_TE_FAST_FORWARD);
    01975       this->SetDirty();
    01976     }
    01977   }
    01978
    01984   virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
    01985   {
    01986     if (!gui_scope) return;
    01987     if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TE_ZOOM_IN, WID_TE_ZOOM_OUT);
    01988   }
    01989
    01990   virtual void OnQueryTextFinished(char *str)
    01991   {
    01992     /* Was 'cancel' pressed? */
    01993     if (str == NULL) return;
    01994
    01995     int32 value;
    01996     if (!StrEmpty(str)) {
    01997       value = atoi(str);
    01998     } else {
    01999       /* An empty string means revert to the default */
    02000       value = DEF_START_YEAR;
    02001     }
    02002     _settings_game.game_creation.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
    02003     SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
    02004
    02005     this->SetDirty();
    02006   }
    02007
    02008   static Hotkey<ScenarioEditorToolbarWindow> scenedit_maintoolbar_hotkeys[];
    02009 };
    02010
    02011 Hotkey<ScenarioEditorToolbarWindow> ScenarioEditorToolbarWindow::scenedit_maintoolbar_hotkeys[] = {
    02012   Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_pause_keys, "pause", MTEHK_PAUSE),
    02013   Hotkey<ScenarioEditorToolbarWindow>((uint16)0, "fastforward", MTEHK_FASTFORWARD),
    02014   Hotkey<ScenarioEditorToolbarWindow>(WKC_F2, "settings", MTEHK_SETTINGS),
    02015   Hotkey<ScenarioEditorToolbarWindow>(WKC_F3, "saveload", MTEHK_SAVEGAME),
    02016   Hotkey<ScenarioEditorToolbarWindow>(WKC_F4, "gen_land", MTEHK_GENLAND),
    02017   Hotkey<ScenarioEditorToolbarWindow>(WKC_F5, "gen_town", MTEHK_GENTOWN),
    02018   Hotkey<ScenarioEditorToolbarWindow>(WKC_F6, "gen_industry", MTEHK_GENINDUSTRY),
    02019   Hotkey<ScenarioEditorToolbarWindow>(WKC_F7, "build_road", MTEHK_BUILD_ROAD),
    02020   Hotkey<ScenarioEditorToolbarWindow>(WKC_F8, "build_docks", MTEHK_BUILD_DOCKS),
    02021   Hotkey<ScenarioEditorToolbarWindow>(WKC_F9, "build_trees", MTEHK_BUILD_TREES),
    02022   Hotkey<ScenarioEditorToolbarWindow>(WKC_F10, "build_sign", MTEHK_SIGN),
    02023   Hotkey<ScenarioEditorToolbarWindow>(WKC_F11, "music", MTEHK_MUSIC),
    02024   Hotkey<ScenarioEditorToolbarWindow>(WKC_F12, "land_info", MTEHK_LANDINFO),
    02025   Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL  | 'S', "small_screenshot", MTEHK_SMALL_SCREENSHOT),
    02026   Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL  | 'P', "zoomedin_screenshot", MTEHK_ZOOMEDIN_SCREENSHOT),
    02027   Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL  | 'D', "defaultzoom_screenshot", MTEHK_DEFAULTZOOM_SCREENSHOT),
    02028   Hotkey<ScenarioEditorToolbarWindow>((uint16)0, "giant_screenshot", MTEHK_GIANT_SCREENSHOT),
    02029   Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_zoomin_keys, "zoomin", MTEHK_ZOOM_IN),
    02030   Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_zoomout_keys, "zoomout", MTEHK_ZOOM_OUT),
    02031   Hotkey<ScenarioEditorToolbarWindow>('L', "terraform", MTEHK_TERRAFORM),
    02032   Hotkey<ScenarioEditorToolbarWindow>('M', "smallmap", MTEHK_SMALLMAP),
    02033   Hotkey<ScenarioEditorToolbarWindow>('V', "extra_viewport", MTEHK_EXTRA_VIEWPORT),
    02034   HOTKEY_LIST_END(ScenarioEditorToolbarWindow)
    02035 };
    02036 Hotkey<ScenarioEditorToolbarWindow> *_scenedit_maintoolbar_hotkeys = ScenarioEditorToolbarWindow::scenedit_maintoolbar_hotkeys;
    02037
    02038 static const NWidgetPart _nested_toolb_scen_inner_widgets[] = {
    02039   NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_PAUSE), SetDataTip(SPR_IMG_PAUSE, STR_TOOLBAR_TOOLTIP_PAUSE_GAME),
    02040   NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_FAST_FORWARD), SetDataTip(SPR_IMG_FASTFORWARD, STR_TOOLBAR_TOOLTIP_FORWARD),
    02041   NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SETTINGS), SetDataTip(SPR_IMG_SETTINGS, STR_TOOLBAR_TOOLTIP_OPTIONS),
    02042   NWidget(WWT_IMGBTN_2, COLOUR_GREY, WID_TE_SAVE), SetDataTip(SPR_IMG_SAVE, STR_SCENEDIT_TOOLBAR_TOOLTIP_SAVE_SCENARIO_LOAD_SCENARIO),
    02043   NWidget(NWID_SPACER),
    02044   NWidget(WWT_PANEL, COLOUR_GREY, WID_TE_SPACER), EndContainer(),
    02045   NWidget(NWID_SPACER),
    02046   NWidget(WWT_PANEL, COLOUR_GREY, WID_TE_DATE_PANEL),
    02047     NWidget(NWID_HORIZONTAL), SetPIP(3, 2, 3),
    02048       NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_DATE_BACKWARD), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD),
    02049       NWidget(WWT_EMPTY, COLOUR_GREY, WID_TE_DATE), SetDataTip(STR_NULL, STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE),
    02050       NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_DATE_FORWARD), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD),
    02051     EndContainer(),
    02052   EndContainer(),
    02053   NWidget(NWID_SPACER),
    02054   NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SMALL_MAP), SetDataTip(SPR_IMG_SMALLMAP, STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY),
    02055   NWidget(NWID_SPACER),
    02056   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ZOOM_IN), SetDataTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN),
    02057   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ZOOM_OUT), SetDataTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT),
    02058   NWidget(NWID_SPACER),
    02059   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_LAND_GENERATE), SetDataTip(SPR_IMG_LANDSCAPING, STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION),
    02060   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_TOWN_GENERATE), SetDataTip(SPR_IMG_TOWN, STR_SCENEDIT_TOOLBAR_TOWN_GENERATION),
    02061   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_INDUSTRY), SetDataTip(SPR_IMG_INDUSTRY, STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION),
    02062   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ROADS), SetDataTip(SPR_IMG_BUILDROAD, STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION),
    02063   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_WATER), SetDataTip(SPR_IMG_BUILDWATER, STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS),
    02064   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_TREES), SetDataTip(SPR_IMG_PLANTTREES, STR_SCENEDIT_TOOLBAR_PLANT_TREES),
    02065   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_SIGNS), SetDataTip(SPR_IMG_SIGN, STR_SCENEDIT_TOOLBAR_PLACE_SIGN),
    02066   NWidget(NWID_SPACER),
    02067   NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_MUSIC_SOUND), SetDataTip(SPR_IMG_MUSIC, STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW),
    02068   NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_HELP), SetDataTip(SPR_IMG_QUERY, STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION),
    02069   NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SWITCH_BAR), SetDataTip(SPR_IMG_SWITCH_TOOLBAR, STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR),
    02070 };
    02071
    02072 static NWidgetBase *MakeScenarioToolbar(int *biggest_index)
    02073 {
    02074   return MakeNWidgets(_nested_toolb_scen_inner_widgets, lengthof(_nested_toolb_scen_inner_widgets), biggest_index, new NWidgetScenarioToolbarContainer());
    02075 }
    02076
    02077 static const NWidgetPart _nested_toolb_scen_widgets[] = {
    02078   NWidgetFunction(MakeScenarioToolbar),
    02079 };
    02080
    02081 static WindowDesc _toolb_scen_desc(
    02082   WDP_MANUAL, 640, 22,
    02083   WC_MAIN_TOOLBAR, WC_NONE,
    02084   WDF_UNCLICK_BUTTONS | WDF_NO_FOCUS,
    02085   _nested_toolb_scen_widgets, lengthof(_nested_toolb_scen_widgets)
    02086 );
    02087
    02089 void AllocateToolbar()
    02090 {
    02091   /* Clean old GUI values; railtype is (re)set by rail_gui.cpp */
    02092   _last_built_roadtype = ROADTYPE_ROAD;
    02093
    02094   if (_game_mode == GM_EDITOR) {
    02095     _preferred_toolbar_size = &_toolb_scen_desc.default_width;
    02096     new ScenarioEditorToolbarWindow(&_toolb_scen_desc);
    02097   } else {
    02098     _preferred_toolbar_size = &_toolb_normal_desc.default_width;
    02099     new MainToolbarWindow(&_toolb_normal_desc);
    02100   }
    02101 }