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