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