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

Generated on Fri Jun 3 05:19:00 2011 for OpenTTD by  doxygen 1.6.1