toolbar_gui.cpp

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