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