# toolbar_gui.cpp

Go to the documentation of this file.

    00001 /* $Id: toolbar_gui.cpp 19132 2010-02-14 16:31:35Z alberth $ */
    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 "variables.h"
    00019 #include "vehicle_gui.h"
    00020 #include "rail_gui.h"
    00021 #include "road_gui.h"
    00022 #include "date_func.h"
    00023 #include "vehicle_func.h"
    00024 #include "sound_func.h"
    00025 #include "terraform_gui.h"
    00026 #include "transparency.h"
    00027 #include "strings_func.h"
    00028 #include "company_func.h"
    00029 #include "company_gui.h"
    00030 #include "vehicle_base.h"
    00031 #include "cheat_func.h"
    00032 #include "transparency_gui.h"
    00033 #include "screenshot.h"
    00034 #include "signs_func.h"
    00035 #include "fios.h"
    00036 #include "functions.h"
    00037 #include "console_gui.h"
    00038 #include "news_gui.h"
    00039 #include "ai/ai_gui.hpp"
    00040 #include "tilehighlight_func.h"
    00041 #include "rail.h"
    00042 #include "widgets/dropdown_type.h"
    00043 #include "company_base.h"
    00044 #include "smallmap_gui.h"
    00045 #include "graph_gui.h"
    00046
    00047 #include "network/network.h"
    00048 #include "network/network_gui.h"
    00049 #include "network/network_func.h"
    00050
    00051 #include "table/strings.h"
    00052 #include "table/sprites.h"
    00053
    00054 RailType _last_built_railtype;
    00055 static RoadType _last_built_roadtype;
    00056
    00057 enum ToolbarMode {
    00058   TB_NORMAL,
    00059   TB_UPPER,
    00060   TB_LOWER
    00061 };
    00062
    00063 enum ToolbarNormalWidgets {
    00064   TBN_PAUSE         = 0,
    00065   TBN_FASTFORWARD,
    00066   TBN_SETTINGS,
    00067   TBN_SAVEGAME,
    00068   TBN_SMALLMAP,
    00069   TBN_TOWNDIRECTORY,
    00070   TBN_SUBSIDIES,
    00071   TBN_STATIONS,
    00072   TBN_FINANCES,
    00073   TBN_COMPANIES,
    00074   TBN_GRAPHICS,
    00075   TBN_LEAGUE,
    00076   TBN_INDUSTRIES,
    00077   TBN_VEHICLESTART,
    00078   TBN_TRAINS        = TBN_VEHICLESTART,
    00079   TBN_ROADVEHS,
    00080   TBN_SHIPS,
    00081   TBN_AIRCRAFTS,
    00082   TBN_ZOOMIN,
    00083   TBN_ZOOMOUT,
    00084   TBN_RAILS,
    00085   TBN_ROADS,
    00086   TBN_WATER,
    00087   TBN_AIR,
    00088   TBN_LANDSCAPE,
    00089   TBN_MUSICSOUND,
    00090   TBN_NEWSREPORT,
    00091   TBN_HELP,
    00092   TBN_SWITCHBAR,
    00093   TBN_END
    00094 };
    00095
    00096 enum ToolbarScenEditorWidgets {
    00097   TBSE_PAUSE        = 0,
    00098   TBSE_FASTFORWARD,
    00099   TBSE_SETTINGS,
    00100   TBSE_SAVESCENARIO,
    00101   TBSE_SPACERPANEL,
    00102   TBSE_DATEPANEL,
    00103   TBSE_DATEBACKWARD,
    00104   TBSE_DATEFORWARD,
    00105   TBSE_SMALLMAP,
    00106   TBSE_ZOOMIN,
    00107   TBSE_ZOOMOUT,
    00108   TBSE_LANDGENERATE,
    00109   TBSE_TOWNGENERATE,
    00110   TBSE_INDUSTRYGENERATE,
    00111   TBSE_BUILDROAD,
    00112   TBSE_BUILDDOCKS,
    00113   TBSE_PLANTTREES,
    00114   TBSE_PLACESIGNS,
    00115   TBSE_DATEPANEL_CONTAINER,
    00116 };
    00117
    00121 class DropDownListCheckedItem : public DropDownListStringItem {
    00122   uint checkmark_width;
    00123 public:
    00124   bool checked;
    00125
    00126   DropDownListCheckedItem(StringID string, int result, bool masked, bool checked) : DropDownListStringItem(string, result, masked), checked(checked)
    00127   {
    00128     this->checkmark_width = GetStringBoundingBox(STR_JUST_CHECKMARK).width + 3;
    00129   }
    00130
    00131   virtual ~DropDownListCheckedItem() {}
    00132
    00133   uint Width() const
    00134   {
    00135     return DropDownListStringItem::Width() + this->checkmark_width;
    00136   }
    00137
    00138   void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
    00139   {
    00140     bool rtl = _dynlang.text_dir == TD_RTL;
    00141     if (this->checked) {
    00142       DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, STR_JUST_CHECKMARK, sel ? TC_WHITE : TC_BLACK);
    00143     }
    00144     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);
    00145   }
    00146 };
    00147
    00151 class DropDownListCompanyItem : public DropDownListItem {
    00152   uint icon_width;
    00153 public:
    00154   bool greyed;
    00155
    00156   DropDownListCompanyItem(int result, bool masked, bool greyed) : DropDownListItem(result, masked), greyed(greyed)
    00157   {
    00158     this->icon_width = GetSpriteSize(SPR_COMPANY_ICON).width;
    00159   }
    00160
    00161   virtual ~DropDownListCompanyItem() {}
    00162
    00163   bool Selectable() const
    00164   {
    00165     return true;
    00166   }
    00167
    00168   uint Width() const
    00169   {
    00170     CompanyID company = (CompanyID)this->result;
    00171     SetDParam(0, company);
    00172     SetDParam(1, company);
    00173     return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_width + 3;
    00174   }
    00175
    00176   void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
    00177   {
    00178     CompanyID company = (CompanyID)this->result;
    00179     bool rtl = _dynlang.text_dir == TD_RTL;
    00180
    00181     /* It's possible the company is deleted while the dropdown is open */
    00182     if (!Company::IsValidID(company)) return;
    00183
    00184     DrawCompanyIcon(company, rtl ? right - this->icon_width - WD_FRAMERECT_RIGHT : left + WD_FRAMERECT_LEFT, top + 1 + (FONT_HEIGHT_NORMAL - 10) / 2);
    00185
    00186     SetDParam(0, company);
    00187     SetDParam(1, company);
    00188     TextColour col;
    00189     if (this->greyed) {
    00190       col = TC_GREY;
    00191     } else {
    00192       col = sel ? TC_WHITE : TC_BLACK;
    00193     }
    00194     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);
    00195   }
    00196 };
    00197
    00201 static void PopupMainToolbMenu(Window *w, int widget, StringID string, int count)
    00202 {
    00203   DropDownList *list = new DropDownList();
    00204   for (int i = 0; i < count; i++) {
    00205     list->push_back(new DropDownListStringItem(string + i, i, false));
    00206   }
    00207   ShowDropDownList(w, list, 0, widget, 140, true, true);
    00208   SndPlayFx(SND_15_BEEP);
    00209 }
    00210
    00212 enum {
    00213   CTMN_CLIENT_LIST = -1,
    00214   CTMN_NEW_COMPANY = -2,
    00215   CTMN_SPECTATE    = -3,
    00216 };
    00217
    00221 static void PopupMainCompanyToolbMenu(Window *w, int widget, int grey = 0)
    00222 {
    00223   DropDownList *list = new DropDownList();
    00224
    00225 #ifdef ENABLE_NETWORK
    00226   if (widget == TBN_COMPANIES && _networking) {
    00227     /* Add the client list button for the companies menu */
    00228     list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, CTMN_CLIENT_LIST, false));
    00229
    00230     if (_local_company == COMPANY_SPECTATOR) {
    00231       list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_NEW_COMPANY, CTMN_NEW_COMPANY, NetworkMaxCompaniesReached()));
    00232     } else {
    00233       list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_SPECTATE, CTMN_SPECTATE, NetworkMaxSpectatorsReached()));
    00234     }
    00235   }
    00236 #endif /* ENABLE_NETWORK */
    00237
    00238   for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
    00239     if (!Company::IsValidID(c)) continue;
    00240     list->push_back(new DropDownListCompanyItem(c, false, HasBit(grey, c)));
    00241   }
    00242
    00243   ShowDropDownList(w, list, _local_company == COMPANY_SPECTATOR ? CTMN_CLIENT_LIST : (int)_local_company, widget, 240, true, true);
    00244   SndPlayFx(SND_15_BEEP);
    00245 }
    00246
    00247
    00248 static ToolbarMode _toolbar_mode;
    00249
    00250 static void SelectSignTool()
    00251 {
    00252   if (_cursor.sprite == SPR_CURSOR_SIGN) {
    00253     ResetObjectToPlace();
    00254   } else {
    00255     SetObjectToPlace(SPR_CURSOR_SIGN, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0);
    00256     _place_proc = PlaceProc_Sign;
    00257   }
    00258 }
    00259
    00260 /* --- Pausing --- */
    00261
    00262 static void ToolbarPauseClick(Window *w)
    00263 {
    00264   if (_networking && !_network_server) return; // only server can pause the game
    00265
    00266   if (DoCommandP(0, PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED, CMD_PAUSE)) SndPlayFx(SND_15_BEEP);
    00267 }
    00268
    00269 /* --- Fast forwarding --- */
    00270
    00271 static void ToolbarFastForwardClick(Window *w)
    00272 {
    00273   _fast_forward ^= true;
    00274   SndPlayFx(SND_15_BEEP);
    00275 }
    00276
    00277 /* --- Options button menu --- */
    00278
    00279 enum OptionMenuEntries {
    00280   OME_GAMEOPTIONS,
    00281   OME_DIFFICULTIES,
    00282   OME_SETTINGS,
    00283   OME_NEWGRFSETTINGS,
    00284   OME_TRANSPARENCIES,
    00285   OME_SHOW_TOWNNAMES,
    00286   OME_SHOW_STATIONNAMES,
    00287   OME_SHOW_WAYPOINTNAMES,
    00288   OME_SHOW_SIGNS,
    00289   OME_FULL_ANIMATION,
    00290   OME_FULL_DETAILS,
    00291   OME_TRANSPARENTBUILDINGS,
    00292   OME_SHOW_STATIONSIGNS,
    00293 };
    00294
    00295 static void ToolbarOptionsClick(Window *w)
    00296 {
    00297   DropDownList *list = new DropDownList();
    00298   list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_GAME_OPTIONS,             OME_GAMEOPTIONS, false));
    00299   list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_DIFFICULTY_SETTINGS,      OME_DIFFICULTIES, false));
    00300   list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_CONFIG_SETTINGS,          OME_SETTINGS, false));
    00301   list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_NEWGRF_SETTINGS,          OME_NEWGRFSETTINGS, false));
    00302   list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS,     OME_TRANSPARENCIES, false));
    00303   list->push_back(new DropDownListItem(-1, false));
    00304   list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED,    OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES)));
    00305   list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false, HasBit(_display_opt, DO_SHOW_STATION_NAMES)));
    00306   list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED,     OME_SHOW_WAYPOINTNAMES, false, HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES)));
    00307   list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_SIGNS_DISPLAYED,         OME_SHOW_SIGNS, false, HasBit(_display_opt, DO_SHOW_SIGNS)));
    00308   list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_ANIMATION,          OME_FULL_ANIMATION, false, HasBit(_display_opt, DO_FULL_ANIMATION)));
    00309   list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_DETAIL,             OME_FULL_DETAILS, false, HasBit(_display_opt, DO_FULL_DETAIL)));
    00310   list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS,   OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES)));
    00311   list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_SIGNS,       OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS)));
    00312
    00313   ShowDropDownList(w, list, 0, TBN_SETTINGS, 140, true, true);
    00314   SndPlayFx(SND_15_BEEP);
    00315 }
    00316
    00317 static void MenuClickSettings(int index)
    00318 {
    00319   switch (index) {
    00320     case OME_GAMEOPTIONS:          ShowGameOptions();                               return;
    00321     case OME_DIFFICULTIES:         ShowGameDifficulty();                            return;
    00322     case OME_SETTINGS:             ShowGameSettings();                              return;
    00323     case OME_NEWGRFSETTINGS:       ShowNewGRFSettings(!_networking, true, true, &_grfconfig);   return;
    00324     case OME_TRANSPARENCIES:       ShowTransparencyToolbar();                       break;
    00325
    00326     case OME_SHOW_TOWNNAMES:       ToggleBit(_display_opt, DO_SHOW_TOWN_NAMES);     break;
    00327     case OME_SHOW_STATIONNAMES:    ToggleBit(_display_opt, DO_SHOW_STATION_NAMES);  break;
    00328     case OME_SHOW_WAYPOINTNAMES:   ToggleBit(_display_opt, DO_SHOW_WAYPOINT_NAMES); break;
    00329     case OME_SHOW_SIGNS:           ToggleBit(_display_opt, DO_SHOW_SIGNS);          break;
    00330     case OME_FULL_ANIMATION:       ToggleBit(_display_opt, DO_FULL_ANIMATION);      break;
    00331     case OME_FULL_DETAILS:         ToggleBit(_display_opt, DO_FULL_DETAIL);         break;
    00332     case OME_TRANSPARENTBUILDINGS: ToggleTransparency(TO_HOUSES);                   break;
    00333     case OME_SHOW_STATIONSIGNS:    ToggleTransparency(TO_SIGNS);                    break;
    00334   }
    00335   MarkWholeScreenDirty();
    00336 }
    00337
    00338 /* --- Saving/loading button menu --- */
    00339
    00340 enum SaveLoadEditorMenuEntries {
    00341   SLEME_SAVE_SCENARIO   = 0,
    00342   SLEME_LOAD_SCENARIO,
    00343   SLEME_LOAD_HEIGHTMAP,
    00344   SLEME_EXIT_TOINTRO,
    00345   SLEME_EXIT_GAME       = 5,
    00346   SLEME_MENUCOUNT,
    00347 };
    00348
    00349 enum SaveLoadNormalMenuEntries {
    00350   SLNME_SAVE_GAME   = 0,
    00351   SLNME_LOAD_GAME,
    00352   SLNME_EXIT_TOINTRO,
    00353   SLNME_EXIT_GAME,
    00354   SLNME_MENUCOUNT,
    00355 };
    00356
    00357 static void ToolbarSaveClick(Window *w)
    00358 {
    00359   PopupMainToolbMenu(w, TBN_SAVEGAME, STR_FILE_MENU_SAVE_GAME, SLNME_MENUCOUNT);
    00360 }
    00361
    00362 static void ToolbarScenSaveOrLoad(Window *w)
    00363 {
    00364   PopupMainToolbMenu(w, TBSE_SAVESCENARIO, STR_SCENEDIT_FILE_MENU_SAVE_SCENARIO, SLEME_MENUCOUNT);
    00365 }
    00366
    00367 static void MenuClickSaveLoad(int index = 0)
    00368 {
    00369   if (_game_mode == GM_EDITOR) {
    00370     switch (index) {
    00371       case SLEME_SAVE_SCENARIO:  ShowSaveLoadDialog(SLD_SAVE_SCENARIO);  break;
    00372       case SLEME_LOAD_SCENARIO:  ShowSaveLoadDialog(SLD_LOAD_SCENARIO);  break;
    00373       case SLEME_LOAD_HEIGHTMAP: ShowSaveLoadDialog(SLD_LOAD_HEIGHTMAP); break;
    00374       case SLEME_EXIT_TOINTRO:   AskExitToGameMenu();                    break;
    00375       case SLEME_EXIT_GAME:      HandleExitGameRequest();                break;
    00376     }
    00377   } else {
    00378     switch (index) {
    00379       case SLNME_SAVE_GAME:      ShowSaveLoadDialog(SLD_SAVE_GAME); break;
    00380       case SLNME_LOAD_GAME:      ShowSaveLoadDialog(SLD_LOAD_GAME); break;
    00381       case SLNME_EXIT_TOINTRO:   AskExitToGameMenu();               break;
    00382       case SLNME_EXIT_GAME:      HandleExitGameRequest();           break;
    00383     }
    00384   }
    00385 }
    00386
    00387 /* --- Map button menu --- */
    00388
    00389 enum MapMenuEntries {
    00390   MME_SHOW_SMALLMAP        = 0,
    00391   MME_SHOW_EXTRAVIEWPORTS,
    00392   MME_SHOW_SIGNLISTS,
    00393   MME_SHOW_TOWNDIRECTORY,
    00394   MME_MENUCOUNT_NORMAL     = 3,
    00395   MME_MENUCOUNT_EDITOR     = 4,
    00396 };
    00397
    00398 static void ToolbarMapClick(Window *w)
    00399 {
    00400   PopupMainToolbMenu(w, TBN_SMALLMAP, STR_MAP_MENU_MAP_OF_WORLD, MME_MENUCOUNT_NORMAL);
    00401 }
    00402
    00403 static void ToolbarScenMapTownDir(Window *w)
    00404 {
    00405   PopupMainToolbMenu(w, TBSE_SMALLMAP, STR_MAP_MENU_MAP_OF_WORLD, MME_MENUCOUNT_EDITOR);
    00406 }
    00407
    00408 static void MenuClickMap(int index)
    00409 {
    00410   switch (index) {
    00411     case MME_SHOW_SMALLMAP:       ShowSmallMap();            break;
    00412     case MME_SHOW_EXTRAVIEWPORTS: ShowExtraViewPortWindow(); break;
    00413     case MME_SHOW_SIGNLISTS:      ShowSignList();            break;
    00414     case MME_SHOW_TOWNDIRECTORY:  if (_game_mode == GM_EDITOR) ShowTownDirectory(); break;
    00415   }
    00416 }
    00417
    00418 /* --- Town button menu --- */
    00419
    00420 static void ToolbarTownClick(Window *w)
    00421 {
    00422   PopupMainToolbMenu(w, TBN_TOWNDIRECTORY, STR_TOWN_MENU_TOWN_DIRECTORY, (_settings_game.economy.found_town == TF_FORBIDDEN) ? 1 : 2);
    00423 }
    00424
    00425 static void MenuClickTown(int index)
    00426 {
    00427   switch (index) {
    00428     case 0: ShowTownDirectory(); break;
    00429     case 1: // setting could be changed when the dropdown was open
    00430       if (_settings_game.economy.found_town != TF_FORBIDDEN) ShowFoundTownWindow();
    00431       break;
    00432   }
    00433 }
    00434
    00435 /* --- Subidies button menu --- */
    00436
    00437 static void ToolbarSubsidiesClick(Window *w)
    00438 {
    00439   PopupMainToolbMenu(w, TBN_SUBSIDIES, STR_SUBSIDIES_MENU_SUBSIDIES, 1);
    00440 }
    00441
    00442 static void MenuClickSubsidies(int index)
    00443 {
    00444   ShowSubsidiesList();
    00445 }
    00446
    00447 /* --- Stations button menu --- */
    00448
    00449 static void ToolbarStationsClick(Window *w)
    00450 {
    00451   PopupMainCompanyToolbMenu(w, TBN_STATIONS);
    00452 }
    00453
    00454 static void MenuClickStations(int index)
    00455 {
    00456   ShowCompanyStations((CompanyID)index);
    00457 }
    00458
    00459 /* --- Finances button menu --- */
    00460
    00461 static void ToolbarFinancesClick(Window *w)
    00462 {
    00463   PopupMainCompanyToolbMenu(w, TBN_FINANCES);
    00464 }
    00465
    00466 static void MenuClickFinances(int index)
    00467 {
    00468   ShowCompanyFinances((CompanyID)index);
    00469 }
    00470
    00471 /* --- Company's button menu --- */
    00472
    00473 static void ToolbarCompaniesClick(Window *w)
    00474 {
    00475   PopupMainCompanyToolbMenu(w, TBN_COMPANIES);
    00476 }
    00477
    00478 static void MenuClickCompany(int index)
    00479 {
    00480 #ifdef ENABLE_NETWORK
    00481   if (_networking) {
    00482     switch (index) {
    00483       case CTMN_CLIENT_LIST:
    00484         ShowClientList();
    00485         return;
    00486
    00487       case CTMN_NEW_COMPANY:
    00488         if (_network_server) {
    00489           DoCommandP(0, 0, _network_own_client_id, CMD_COMPANY_CTRL);
    00490         } else {
    00491           NetworkSend_Command(0, 0, 0, CMD_COMPANY_CTRL, NULL, NULL, _local_company);
    00492         }
    00493         return;
    00494
    00495       case CTMN_SPECTATE:
    00496         if (_network_server) {
    00497           NetworkServerDoMove(CLIENT_ID_SERVER, COMPANY_SPECTATOR);
    00498           MarkWholeScreenDirty();
    00499         } else {
    00500           NetworkClientRequestMove(COMPANY_SPECTATOR);
    00501         }
    00502         return;
    00503     }
    00504   }
    00505 #endif /* ENABLE_NETWORK */
    00506   ShowCompany((CompanyID)index);
    00507 }
    00508
    00509 /* --- Graphs button menu --- */
    00510
    00511 static void ToolbarGraphsClick(Window *w)
    00512 {
    00513   PopupMainToolbMenu(w, TBN_GRAPHICS, STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH, (_toolbar_mode == TB_NORMAL) ? 6 : 8);
    00514 }
    00515
    00516 static void MenuClickGraphs(int index)
    00517 {
    00518   switch (index) {
    00519     case 0: ShowOperatingProfitGraph();    break;
    00520     case 1: ShowIncomeGraph();             break;
    00521     case 2: ShowDeliveredCargoGraph();     break;
    00522     case 3: ShowPerformanceHistoryGraph(); break;
    00523     case 4: ShowCompanyValueGraph();       break;
    00524     case 5: ShowCargoPaymentRates();       break;
    00525     /* functions for combined graphs/league button */
    00526     case 6: ShowCompanyLeagueTable();      break;
    00527     case 7: ShowPerformanceRatingDetail(); break;
    00528   }
    00529 }
    00530
    00531 /* --- League button menu --- */
    00532
    00533 static void ToolbarLeagueClick(Window *w)
    00534 {
    00535   PopupMainToolbMenu(w, TBN_LEAGUE, STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE, 2);
    00536 }
    00537
    00538 static void MenuClickLeague(int index)
    00539 {
    00540   switch (index) {
    00541     case 0: ShowCompanyLeagueTable();      break;
    00542     case 1: ShowPerformanceRatingDetail(); break;
    00543   }
    00544 }
    00545
    00546 /* --- Industries button menu --- */
    00547
    00548 static void ToolbarIndustryClick(Window *w)
    00549 {
    00550   /* Disable build-industry menu if we are a spectator */
    00551   PopupMainToolbMenu(w, TBN_INDUSTRIES, STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY, (_local_company == COMPANY_SPECTATOR) ? 1 : 2);
    00552 }
    00553
    00554 static void MenuClickIndustry(int index)
    00555 {
    00556   switch (index) {
    00557     case 0: ShowIndustryDirectory();   break;
    00558     case 1: ShowBuildIndustryWindow(); break;
    00559   }
    00560 }
    00561
    00562 /* --- Trains button menu + 1 helper function for all vehicles. --- */
    00563
    00564 static void ToolbarVehicleClick(Window *w, VehicleType veh)
    00565 {
    00566   const Vehicle *v;
    00567   int dis = ~0;
    00568
    00569   FOR_ALL_VEHICLES(v) {
    00570     if (v->type == veh && v->IsPrimaryVehicle()) ClrBit(dis, v->owner);
    00571   }
    00572   PopupMainCompanyToolbMenu(w, TBN_VEHICLESTART + veh, dis);
    00573 }
    00574
    00575
    00576 static void ToolbarTrainClick(Window *w)
    00577 {
    00578   ToolbarVehicleClick(w, VEH_TRAIN);
    00579 }
    00580
    00581 static void MenuClickShowTrains(int index)
    00582 {
    00583   ShowVehicleListWindow((CompanyID)index, VEH_TRAIN);
    00584 }
    00585
    00586 /* --- Road vehicle button menu --- */
    00587
    00588 static void ToolbarRoadClick(Window *w)
    00589 {
    00590   ToolbarVehicleClick(w, VEH_ROAD);
    00591 }
    00592
    00593 static void MenuClickShowRoad(int index)
    00594 {
    00595   ShowVehicleListWindow((CompanyID)index, VEH_ROAD);
    00596 }
    00597
    00598 /* --- Ship button menu --- */
    00599
    00600 static void ToolbarShipClick(Window *w)
    00601 {
    00602   ToolbarVehicleClick(w, VEH_SHIP);
    00603 }
    00604
    00605 static void MenuClickShowShips(int index)
    00606 {
    00607   ShowVehicleListWindow((CompanyID)index, VEH_SHIP);
    00608 }
    00609
    00610 /* --- Aircraft button menu --- */
    00611
    00612 static void ToolbarAirClick(Window *w)
    00613 {
    00614   ToolbarVehicleClick(w, VEH_AIRCRAFT);
    00615 }
    00616
    00617 static void MenuClickShowAir(int index)
    00618 {
    00619   ShowVehicleListWindow((CompanyID)index, VEH_AIRCRAFT);
    00620 }
    00621
    00622 /* --- Zoom in button --- */
    00623
    00624 static void ToolbarZoomInClick(Window *w)
    00625 {
    00626   if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) {
    00627     w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)TBSE_ZOOMIN : (byte)TBN_ZOOMIN);
    00628     SndPlayFx(SND_15_BEEP);
    00629   }
    00630 }
    00631
    00632 /* --- Zoom out button --- */
    00633
    00634 static void ToolbarZoomOutClick(Window *w)
    00635 {
    00636   if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) {
    00637     w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)TBSE_ZOOMOUT : (byte)TBN_ZOOMOUT);
    00638     SndPlayFx(SND_15_BEEP);
    00639   }
    00640 }
    00641
    00642 /* --- Rail button menu --- */
    00643
    00644 static void ToolbarBuildRailClick(Window *w)
    00645 {
    00646   const Company *c = Company::Get(_local_company);
    00647   DropDownList *list = new DropDownList();
    00648   for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
    00649     const RailtypeInfo *rti = GetRailTypeInfo(rt);
    00650     /* Skip rail type if it has no label */
    00651     if (rti->label == 0) continue;
    00652     list->push_back(new DropDownListStringItem(rti->strings.menu_text, rt, !HasBit(c->avail_railtypes, rt)));
    00653   }
    00654   ShowDropDownList(w, list, _last_built_railtype, TBN_RAILS, 140, true, true);
    00655   SndPlayFx(SND_15_BEEP);
    00656 }
    00657
    00658 static void MenuClickBuildRail(int index)
    00659 {
    00660   _last_built_railtype = (RailType)index;
    00661   ShowBuildRailToolbar(_last_built_railtype, -1);
    00662 }
    00663
    00664 /* --- Road button menu --- */
    00665
    00666 static void ToolbarBuildRoadClick(Window *w)
    00667 {
    00668   const Company *c = Company::Get(_local_company);
    00669   DropDownList *list = new DropDownList();
    00670   for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
    00671     /* The standard road button is *always* available */
    00672     list->push_back(new DropDownListStringItem(STR_ROAD_MENU_ROAD_CONSTRUCTION + rt, rt, !(HasBit(c->avail_roadtypes, rt) || rt == ROADTYPE_ROAD)));
    00673   }
    00674   ShowDropDownList(w, list, _last_built_roadtype, TBN_ROADS, 140, true, true);
    00675   SndPlayFx(SND_15_BEEP);
    00676 }
    00677
    00678 static void MenuClickBuildRoad(int index)
    00679 {
    00680   _last_built_roadtype = (RoadType)index;
    00681   ShowBuildRoadToolbar(_last_built_roadtype);
    00682 }
    00683
    00684 /* --- Water button menu --- */
    00685
    00686 static void ToolbarBuildWaterClick(Window *w)
    00687 {
    00688   PopupMainToolbMenu(w, TBN_WATER, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 1);
    00689 }
    00690
    00691 static void MenuClickBuildWater(int index)
    00692 {
    00693   ShowBuildDocksToolbar();
    00694 }
    00695
    00696 /* --- Airport button menu --- */
    00697
    00698 static void ToolbarBuildAirClick(Window *w)
    00699 {
    00700   PopupMainToolbMenu(w, TBN_AIR, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 1);
    00701 }
    00702
    00703 static void MenuClickBuildAir(int index)
    00704 {
    00705   ShowBuildAirToolbar();
    00706 }
    00707
    00708 /* --- Forest button menu --- */
    00709
    00710 static void ToolbarForestClick(Window *w)
    00711 {
    00712   PopupMainToolbMenu(w, TBN_LANDSCAPE, STR_LANDSCAPING_MENU_LANDSCAPING, 3);
    00713 }
    00714
    00715 static void MenuClickForest(int index)
    00716 {
    00717   switch (index) {
    00718     case 0: ShowTerraformToolbar();  break;
    00719     case 1: ShowBuildTreesToolbar(); break;
    00720     case 2: SelectSignTool();        break;
    00721   }
    00722 }
    00723
    00724 /* --- Music button menu --- */
    00725
    00726 static void ToolbarMusicClick(Window *w)
    00727 {
    00728   PopupMainToolbMenu(w, TBN_MUSICSOUND, STR_TOOLBAR_SOUND_MUSIC, 1);
    00729 }
    00730
    00731 static void MenuClickMusicWindow(int index)
    00732 {
    00733   ShowMusicWindow();
    00734 }
    00735
    00736 /* --- Newspaper button menu --- */
    00737
    00738 static void ToolbarNewspaperClick(Window *w)
    00739 {
    00740   PopupMainToolbMenu(w, TBN_NEWSREPORT, STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT, 3);
    00741 }
    00742
    00743 static void MenuClickNewspaper(int index)
    00744 {
    00745   switch (index) {
    00746     case 0: ShowLastNewsMessage(); break;
    00747     case 1: ShowMessageOptions();  break;
    00748     case 2: ShowMessageHistory();  break;
    00749   }
    00750 }
    00751
    00752 /* --- Help button menu --- */
    00753
    00754 static void ToolbarHelpClick(Window *w)
    00755 {
    00756   PopupMainToolbMenu(w, TBN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, 7);
    00757 }
    00758
    00759 static void MenuClickSmallScreenshot()
    00760 {
    00761   MakeScreenshot(SC_VIEWPORT, NULL);
    00762 }
    00763
    00764 static void MenuClickWorldScreenshot()
    00765 {
    00766   MakeScreenshot(SC_WORLD, NULL);
    00767 }
    00768
    00769 static void MenuClickHelp(int index)
    00770 {
    00771   switch (index) {
    00772     case 0: PlaceLandBlockInfo();       break;
    00773     case 2: IConsoleSwitch();           break;
    00774     case 3: ShowAIDebugWindow();        break;
    00775     case 4: MenuClickSmallScreenshot(); break;
    00776     case 5: MenuClickWorldScreenshot(); break;
    00777     case 6: ShowAboutWindow();          break;
    00778   }
    00779 }
    00780
    00781 /* --- Switch toolbar button --- */
    00782
    00783 static void ToolbarSwitchClick(Window *w)
    00784 {
    00785   if (_toolbar_mode != TB_LOWER) {
    00786     _toolbar_mode = TB_LOWER;
    00787   } else {
    00788     _toolbar_mode = TB_UPPER;
    00789   }
    00790
    00791   w->ReInit();
    00792   w->SetWidgetLoweredState(TBN_SWITCHBAR, _toolbar_mode == TB_LOWER);
    00793   SndPlayFx(SND_15_BEEP);
    00794 }
    00795
    00796 /* --- Scenario editor specific handlers. */
    00797
    00798 static void ToolbarScenDateBackward(Window *w)
    00799 {
    00800   /* don't allow too fast scrolling */
    00801   if ((w->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
    00802     w->HandleButtonClick(TBSE_DATEBACKWARD);
    00803     w->SetDirty();
    00804
    00805     _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year - 1, MIN_YEAR, MAX_YEAR);
    00806     SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
    00807   }
    00808   _left_button_clicked = false;
    00809 }
    00810
    00811 static void ToolbarScenDateForward(Window *w)
    00812 {
    00813   /* don't allow too fast scrolling */
    00814   if ((w->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
    00815     w->HandleButtonClick(TBSE_DATEFORWARD);
    00816     w->SetDirty();
    00817
    00818     _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year + 1, MIN_YEAR, MAX_YEAR);
    00819     SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
    00820   }
    00821   _left_button_clicked = false;
    00822 }
    00823
    00824 static void ToolbarScenGenLand(Window *w)
    00825 {
    00826   w->HandleButtonClick(TBSE_LANDGENERATE);
    00827   SndPlayFx(SND_15_BEEP);
    00828
    00829   ShowEditorTerraformToolbar();
    00830 }
    00831
    00832
    00833 static void ToolbarScenGenTown(Window *w)
    00834 {
    00835   w->HandleButtonClick(TBSE_TOWNGENERATE);
    00836   SndPlayFx(SND_15_BEEP);
    00837   ShowFoundTownWindow();
    00838 }
    00839
    00840 static void ToolbarScenGenIndustry(Window *w)
    00841 {
    00842   w->HandleButtonClick(TBSE_INDUSTRYGENERATE);
    00843   SndPlayFx(SND_15_BEEP);
    00844   ShowBuildIndustryWindow();
    00845 }
    00846
    00847 static void ToolbarScenBuildRoad(Window *w)
    00848 {
    00849   w->HandleButtonClick(TBSE_BUILDROAD);
    00850   SndPlayFx(SND_15_BEEP);
    00851   ShowBuildRoadScenToolbar();
    00852 }
    00853
    00854 static void ToolbarScenBuildDocks(Window *w)
    00855 {
    00856   w->HandleButtonClick(TBSE_BUILDDOCKS);
    00857   SndPlayFx(SND_15_BEEP);
    00858   ShowBuildDocksScenToolbar();
    00859 }
    00860
    00861 static void ToolbarScenPlantTrees(Window *w)
    00862 {
    00863   w->HandleButtonClick(TBSE_PLANTTREES);
    00864   SndPlayFx(SND_15_BEEP);
    00865   ShowBuildTreesToolbar();
    00866 }
    00867
    00868 static void ToolbarScenPlaceSign(Window *w)
    00869 {
    00870   w->HandleButtonClick(TBSE_PLACESIGNS);
    00871   SndPlayFx(SND_15_BEEP);
    00872   SelectSignTool();
    00873 }
    00874
    00875 static void ToolbarBtn_NULL(Window *w)
    00876 {
    00877 }
    00878
    00879 typedef void MenuClickedProc(int index);
    00880
    00881 static MenuClickedProc * const _menu_clicked_procs[] = {
    00882   NULL,                 // 0
    00883   NULL,                 // 1
    00884   MenuClickSettings,    // 2
    00885   MenuClickSaveLoad,    // 3
    00886   MenuClickMap,         // 4
    00887   MenuClickTown,        // 5
    00888   MenuClickSubsidies,   // 6
    00889   MenuClickStations,    // 7
    00890   MenuClickFinances,    // 8
    00891   MenuClickCompany,     // 9
    00892   MenuClickGraphs,      // 10
    00893   MenuClickLeague,      // 11
    00894   MenuClickIndustry,    // 12
    00895   MenuClickShowTrains,  // 13
    00896   MenuClickShowRoad,    // 14
    00897   MenuClickShowShips,   // 15
    00898   MenuClickShowAir,     // 16
    00899   MenuClickMap,         // 17
    00900   NULL,                 // 18
    00901   MenuClickBuildRail,   // 19
    00902   MenuClickBuildRoad,   // 20
    00903   MenuClickBuildWater,  // 21
    00904   MenuClickBuildAir,    // 22
    00905   MenuClickForest,      // 23
    00906   MenuClickMusicWindow, // 24
    00907   MenuClickNewspaper,   // 25
    00908   MenuClickHelp,        // 26
    00909 };
    00910
    00912 class NWidgetToolbarContainer : public NWidgetContainer {
    00913   bool visible[TBN_END];
    00914 protected:
    00915   uint spacers;
    00916
    00917 public:
    00918   NWidgetToolbarContainer() : NWidgetContainer(NWID_HORIZONTAL)
    00919   {
    00920   }
    00921
    00927   bool IsButton(WidgetType type) const
    00928   {
    00929     return type == WWT_IMGBTN || type == WWT_IMGBTN_2 || type == WWT_PUSHIMGBTN;
    00930   }
    00931
    00932   void SetupSmallestSize(Window *w, bool init_array)
    00933   {
    00934     this->smallest_x = 0; // Biggest child
    00935     this->smallest_y = 0; // Biggest child
    00936     this->fill_x = 1;
    00937     this->fill_y = 0;
    00938     this->resize_x = 1; // We only resize in this direction
    00939     this->resize_y = 0; // We never resize in this direction
    00940     this->spacers = 0;
    00941
    00942     /* First initialise some variables... */
    00943     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
    00944       child_wid->SetupSmallestSize(w, init_array);
    00945       this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom);
    00946       if (this->IsButton(child_wid->type)) {
    00947         this->smallest_x = max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right);
    00948       } else if (child_wid->type == NWID_SPACER) {
    00949         this->spacers++;
    00950       }
    00951     }
    00952
    00953     /* ... then in a second pass make sure the 'current' heights are set. Won't change ever. */
    00954     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
    00955       child_wid->current_y = this->smallest_y;
    00956       if (!this->IsButton(child_wid->type)) {
    00957         child_wid->current_x = child_wid->smallest_x;
    00958       }
    00959     }
    00960   }
    00961
    00962   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl)
    00963   {
    00964     assert(given_width >= this->smallest_x && given_height >= this->smallest_y);
    00965
    00966     this->pos_x = x;
    00967     this->pos_y = y;
    00968     this->current_x = given_width;
    00969     this->current_y = given_height;
    00970
    00971     /* Figure out what are the visible buttons */
    00972     memset(this->visible, 0, sizeof(this->visible));
    00973     uint arrangable_count, button_count, spacer_count;
    00974     const byte *arrangement = GetButtonArrangement(given_width, arrangable_count, button_count, spacer_count);
    00975     for (uint i = 0; i < arrangable_count; i++) {
    00976       this->visible[arrangement[i]] = true;
    00977     }
    00978
    00979     /* Create us ourselves a quick lookup table */
    00980     NWidgetBase *widgets[TBN_END];
    00981     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
    00982       if (child_wid->type == NWID_SPACER) continue;
    00983       widgets[((NWidgetCore*)child_wid)->index] = child_wid;
    00984     }
    00985
    00986     /* Now assign the widgets to their rightful place */
    00987     uint position = 0; // Place to put next child relative to origin of the container.
    00988     uint spacer_space = max(0, (int)given_width - (int)(button_count * this->smallest_x)); // Remaining spacing for 'spacer' widgets
    00989     uint button_space = given_width - spacer_space; // Remaining spacing for the buttons
    00990     uint spacer_i = 0;
    00991     uint button_i = 0;
    00992
    00993     /* Index into the arrangement indices. The macro lastof cannot be used here! */
    00994     const byte *cur_wid = rtl ? &arrangement[arrangable_count - 1] : arrangement;
    00995     for (uint i = 0; i < arrangable_count; i++) {
    00996       NWidgetBase *child_wid = widgets[*cur_wid];
    00997       /* If we have to give space to the spacers, do that */
    00998       if (spacer_space != 0) {
    00999         NWidgetBase *possible_spacer = rtl ? child_wid->next : child_wid->prev;
    01000         if (possible_spacer != NULL && possible_spacer->type == NWID_SPACER) {
    01001           uint add = spacer_space / (spacer_count - spacer_i);
    01002           position += add;
    01003           spacer_space -= add;
    01004           spacer_i++;
    01005         }
    01006       }
    01007
    01008       /* Buttons can be scaled, the others not. */
    01009       if (this->IsButton(child_wid->type)) {
    01010         child_wid->current_x = button_space / (button_count - button_i);
    01011         button_space -= child_wid->current_x;
    01012         button_i++;
    01013       }
    01014       child_wid->AssignSizePosition(sizing, x + position, y, child_wid->current_x, this->current_y, rtl);
    01015       position += child_wid->current_x;
    01016
    01017       if (rtl) {
    01018         cur_wid--;
    01019       } else {
    01020         cur_wid++;
    01021       }
    01022     }
    01023   }
    01024
    01025   /* virtual */ void Draw(const Window *w)
    01026   {
    01027     /* Draw brown-red toolbar bg. */
    01028     GfxFillRect(this->pos_x, this->pos_y, this->pos_x + this->current_x - 1, this->pos_y + this->current_y - 1, 0xB2);
    01029     GfxFillRect(this->pos_x, this->pos_y, this->pos_x + this->current_x - 1, this->pos_y + this->current_y - 1, 0xB4, FILLRECT_CHECKER);
    01030
    01031     bool rtl = _dynlang.text_dir == TD_RTL;
    01032     for (NWidgetBase *child_wid = rtl ? this->tail : this->head; child_wid != NULL; child_wid = rtl ? child_wid->prev : child_wid->next) {
    01033       if (child_wid->type == NWID_SPACER) continue;
    01034       if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
    01035
    01036       child_wid->Draw(w);
    01037     }
    01038   }
    01039
    01040   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y)
    01041   {
    01042     if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL;
    01043
    01044     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
    01045       if (child_wid->type == NWID_SPACER) continue;
    01046       if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
    01047
    01048       NWidgetCore *nwid = child_wid->GetWidgetFromPos(x, y);
    01049       if (nwid != NULL) return nwid;
    01050     }
    01051     return NULL;
    01052   }
    01053
    01062   virtual const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const = 0;
    01063 };
    01064
    01066 class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
    01067   /* virtual */ const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
    01068   {
    01069     static const uint SMALLEST_ARRANGEMENT = 14;
    01070     static const uint BIGGEST_ARRANGEMENT  = 19;
    01071     static const byte arrange14[] = {
    01072       0,  1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 27,
    01073       2,  3,  4,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 27,
    01074     };
    01075     static const byte arrange15[] = {
    01076       0,  1,  4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
    01077       0,  2,  4,  3,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 27,
    01078     };
    01079     static const byte arrange16[] = {
    01080       0,  1,  2,  4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
    01081       0,  1,  3,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 17, 18, 27,
    01082     };
    01083     static const byte arrange17[] = {
    01084       0,  1,  2,  4,  6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
    01085       0,  1,  3,  4,  6,  5,  7,  8,  9, 10, 12, 24, 25, 26, 17, 18, 27,
    01086     };
    01087     static const byte arrange18[] = {
    01088       0,  1,  2,  4,  5,  6,  7,  8,  9, 12, 19, 20, 21, 22, 23, 17, 18, 27,
    01089       0,  1,  3,  4,  5,  6,  7, 10, 13, 14, 15, 16, 24, 25, 26, 17, 18, 27,
    01090     };
    01091     static const byte arrange19[] = {
    01092       0,  1,  2,  4,  5,  6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 27,
    01093       0,  1,  3,  4,  7,  8,  9, 10, 12, 25, 19, 20, 21, 22, 23, 26, 17, 18, 27,
    01094     };
    01095     static const byte arrange_all[] = {
    01096       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,
    01097     };
    01098
    01099     /* If at least BIGGEST_ARRANGEMENT fit, just spread all the buttons nicely */
    01100     uint full_buttons = max((width + this->smallest_x - 1) / this->smallest_x, SMALLEST_ARRANGEMENT);
    01101     if (full_buttons > BIGGEST_ARRANGEMENT) {
    01102       button_count = arrangable_count = lengthof(arrange_all);
    01103       spacer_count = this->spacers;
    01104       return arrange_all;
    01105     }
    01106
    01107     /* Introduce the split toolbar */
    01108     static const byte * const arrangements[] = { arrange14, arrange15, arrange16, arrange17, arrange18, arrange19 };
    01109
    01110     button_count = arrangable_count = full_buttons;
    01111     spacer_count = this->spacers;
    01112     return arrangements[full_buttons - SMALLEST_ARRANGEMENT] + ((_toolbar_mode == TB_LOWER) ? full_buttons : 0);
    01113   }
    01114 };
    01115
    01117 class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer {
    01118   uint panel_widths[2];
    01119
    01120   void SetupSmallestSize(Window *w, bool init_array)
    01121   {
    01122     this->NWidgetToolbarContainer::SetupSmallestSize(w, init_array);
    01123
    01124     /* Find the size of panel_widths */
    01125     uint i = 0;
    01126     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
    01127       if (child_wid->type == NWID_SPACER || this->IsButton(child_wid->type)) continue;
    01128
    01129       assert(i < lengthof(this->panel_widths));
    01130       this->panel_widths[i++] = child_wid->current_x;
    01131     }
    01132   }
    01133
    01134   /* virtual */ const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
    01135   {
    01136     static const byte arrange_all[] = {
    01137       0, 1, 2, 3, 4, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24, 26,
    01138     };
    01139     static const byte arrange_nopanel[] = {
    01140       0, 1, 2, 3, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24, 26,
    01141     };
    01142     static const byte arrange_switch[] = {
    01143       18,  8, 11, 12, 13, 14, 15, 16, 17, 27,
    01144        0,  1,  2,  3, 18,  9, 10, 24, 26, 27,
    01145     };
    01146
    01147     /* If we can place all buttons *and* the panels, show them. */
    01148     uint min_full_width = (lengthof(arrange_all) - lengthof(this->panel_widths)) * this->smallest_x + this->panel_widths[0] + this->panel_widths[1];
    01149     if (width >= min_full_width) {
    01150       width -= this->panel_widths[0] + this->panel_widths[1];
    01151       arrangable_count = lengthof(arrange_all);
    01152       button_count = arrangable_count - 2;
    01153       spacer_count = this->spacers;
    01154       return arrange_all;
    01155     }
    01156
    01157     /* 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 */
    01158     uint min_small_width = (lengthof(arrange_switch) - lengthof(this->panel_widths)) * this->smallest_x / 2 + this->panel_widths[1];
    01159     if (width > min_small_width) {
    01160       width -= this->panel_widths[1];
    01161       arrangable_count = lengthof(arrange_nopanel);
    01162       button_count = arrangable_count - 1;
    01163       spacer_count = this->spacers - 1;
    01164       return arrange_nopanel;
    01165     }
    01166
    01167     /* Split toolbar */
    01168     width -= this->panel_widths[1];
    01169     arrangable_count = lengthof(arrange_switch) / 2;
    01170     button_count = arrangable_count - 1;
    01171     spacer_count = 0;
    01172     return arrange_switch + ((_toolbar_mode == TB_LOWER) ? arrangable_count : 0);
    01173   }
    01174 };
    01175
    01176 /* --- Toolbar handling for the 'normal' case */
    01177
    01178 typedef void ToolbarButtonProc(Window *w);
    01179
    01180 static ToolbarButtonProc * const _toolbar_button_procs[] = {
    01181   ToolbarPauseClick,
    01182   ToolbarFastForwardClick,
    01183   ToolbarOptionsClick,
    01184   ToolbarSaveClick,
    01185   ToolbarMapClick,
    01186   ToolbarTownClick,
    01187   ToolbarSubsidiesClick,
    01188   ToolbarStationsClick,
    01189   ToolbarFinancesClick,
    01190   ToolbarCompaniesClick,
    01191   ToolbarGraphsClick,
    01192   ToolbarLeagueClick,
    01193   ToolbarIndustryClick,
    01194   ToolbarTrainClick,
    01195   ToolbarRoadClick,
    01196   ToolbarShipClick,
    01197   ToolbarAirClick,
    01198   ToolbarZoomInClick,
    01199   ToolbarZoomOutClick,
    01200   ToolbarBuildRailClick,
    01201   ToolbarBuildRoadClick,
    01202   ToolbarBuildWaterClick,
    01203   ToolbarBuildAirClick,
    01204   ToolbarForestClick,
    01205   ToolbarMusicClick,
    01206   ToolbarNewspaperClick,
    01207   ToolbarHelpClick,
    01208   ToolbarSwitchClick,
    01209 };
    01210
    01211 struct MainToolbarWindow : Window {
    01212   MainToolbarWindow(const WindowDesc *desc) : Window()
    01213   {
    01214     this->InitNested(desc, 0);
    01215
    01216     CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
    01217     this->SetWidgetDisabledState(TBN_PAUSE, _networking && !_network_server); // if not server, disable pause button
    01218     this->SetWidgetDisabledState(TBN_FASTFORWARD, _networking); // if networking, disable fast-forward button
    01219     PositionMainToolbar(this);
    01220     DoZoomInOutWindow(ZOOM_NONE, this);
    01221   }
    01222
    01223   virtual void OnPaint()
    01224   {
    01225     /* If spectator, disable all construction buttons
    01226      * ie : Build road, rail, ships, airports and landscaping
    01227      * Since enabled state is the default, just disable when needed */
    01228     this->SetWidgetsDisabledState(_local_company == COMPANY_SPECTATOR, TBN_RAILS, TBN_ROADS, TBN_WATER, TBN_AIR, TBN_LANDSCAPE, WIDGET_LIST_END);
    01229     /* disable company list drop downs, if there are no companies */
    01230     this->SetWidgetsDisabledState(Company::GetNumItems() == 0, TBN_STATIONS, TBN_FINANCES, TBN_TRAINS, TBN_ROADVEHS, TBN_SHIPS, TBN_AIRCRAFTS, WIDGET_LIST_END);
    01231
    01232     this->SetWidgetDisabledState(TBN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN));
    01233     this->SetWidgetDisabledState(TBN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT));
    01234
    01235     this->DrawWidgets();
    01236   }
    01237
    01238   virtual void OnClick(Point pt, int widget, int click_count)
    01239   {
    01240     if (_game_mode != GM_MENU && !this->IsWidgetDisabled(widget)) _toolbar_button_procs[widget](this);
    01241   }
    01242
    01243   virtual void OnDropdownSelect(int widget, int index)
    01244   {
    01245     _menu_clicked_procs[widget](index);
    01246   }
    01247
    01248   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
    01249   {
    01250     switch (keycode) {
    01251       case WKC_F1: case WKC_PAUSE: ToolbarPauseClick(this); break;
    01252       case WKC_F2: ShowGameOptions(); break;
    01253       case WKC_F3: MenuClickSaveLoad(); break;
    01254       case WKC_F4: ShowSmallMap(); break;
    01255       case WKC_F5: ShowTownDirectory(); break;
    01256       case WKC_F6: ShowSubsidiesList(); break;
    01257       case WKC_F7: ShowCompanyStations(_local_company); break;
    01258       case WKC_F8: ShowCompanyFinances(_local_company); break;
    01259       case WKC_F9: ShowCompany(_local_company); break;
    01260       case WKC_F10: ShowOperatingProfitGraph(); break;
    01261       case WKC_F11: ShowCompanyLeagueTable(); break;
    01262       case WKC_F12: ShowBuildIndustryWindow(); break;
    01263       case WKC_SHIFT | WKC_F1: ShowVehicleListWindow(_local_company, VEH_TRAIN); break;
    01264       case WKC_SHIFT | WKC_F2: ShowVehicleListWindow(_local_company, VEH_ROAD); break;
    01265       case WKC_SHIFT | WKC_F3: ShowVehicleListWindow(_local_company, VEH_SHIP); break;
    01266       case WKC_SHIFT | WKC_F4: ShowVehicleListWindow(_local_company, VEH_AIRCRAFT); break;
    01267       case WKC_NUM_PLUS: // Fall through
    01268       case WKC_EQUALS: // Fall through
    01269       case WKC_SHIFT | WKC_EQUALS: // Fall through
    01270       case WKC_SHIFT | WKC_F5: ToolbarZoomInClick(this); break;
    01271       case WKC_NUM_MINUS: // Fall through
    01272       case WKC_MINUS: // Fall through
    01273       case WKC_SHIFT | WKC_MINUS: // Fall through
    01274       case WKC_SHIFT | WKC_F6: ToolbarZoomOutClick(this); break;
    01275       case WKC_SHIFT | WKC_F7: if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype, -1); break;
    01276       case WKC_SHIFT | WKC_F8: ShowBuildRoadToolbar(_last_built_roadtype); break;
    01277       case WKC_SHIFT | WKC_F9: ShowBuildDocksToolbar(); break;
    01278       case WKC_SHIFT | WKC_F10: if (CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) ShowBuildAirToolbar(); break;
    01279       case WKC_SHIFT | WKC_F11: ShowBuildTreesToolbar(); break;
    01280       case WKC_SHIFT | WKC_F12: ShowMusicWindow(); break;
    01281       case WKC_CTRL  | 'S': MenuClickSmallScreenshot(); break;
    01282       case WKC_CTRL  | 'G': MenuClickWorldScreenshot(); break;
    01283       case WKC_CTRL | WKC_ALT | 'C': if (!_networking) ShowCheatWindow(); break;
    01284       case 'A': if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype, 4); break; // Invoke Autorail
    01285       case 'L': ShowTerraformToolbar(); break;
    01286       case 'Q': case 'W': case 'E': case 'D': ShowTerraformToolbarWithTool(key, keycode); break;
    01287       case 'M': ShowSmallMap(); break;
    01288       case 'V': ShowExtraViewPortWindow(); break;
    01289       default: return ES_NOT_HANDLED;
    01290     }
    01291     return ES_HANDLED;
    01292   }
    01293
    01294   virtual void OnPlaceObject(Point pt, TileIndex tile)
    01295   {
    01296     _place_proc(tile);
    01297   }
    01298
    01299   virtual void OnTick()
    01300   {
    01301     if (this->IsWidgetLowered(TBN_PAUSE) != !!_pause_mode) {
    01302       this->ToggleWidgetLoweredState(TBN_PAUSE);
    01303       this->SetWidgetDirty(TBN_PAUSE);
    01304     }
    01305
    01306     if (this->IsWidgetLowered(TBN_FASTFORWARD) != !!_fast_forward) {
    01307       this->ToggleWidgetLoweredState(TBN_FASTFORWARD);
    01308       this->SetWidgetDirty(TBN_FASTFORWARD);
    01309     }
    01310   }
    01311
    01312   virtual void OnTimeout()
    01313   {
    01314     /* We do not want to automatically raise the pause, fast forward and
    01315      * switchbar buttons; they have to stay down when pressed etc. */
    01316     for (uint i = TBN_SETTINGS; i < TBN_SWITCHBAR; i++) {
    01317       if (this->IsWidgetLowered(i)) {
    01318         this->RaiseWidget(i);
    01319         this->SetWidgetDirty(i);
    01320       }
    01321     }
    01322   }
    01323
    01324   virtual void OnInvalidateData(int data)
    01325   {
    01326     if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, TBN_ZOOMIN, TBN_ZOOMOUT);
    01327   }
    01328 };
    01329
    01330 static NWidgetBase *MakeMainToolbar(int *biggest_index)
    01331 {
    01333   static const SpriteID toolbar_button_sprites[] = {
    01334     SPR_IMG_PAUSE,           // TBN_PAUSE
    01335     SPR_IMG_FASTFORWARD,     // TBN_FASTFORWARD
    01336     SPR_IMG_SETTINGS,        // TBN_SETTINGS
    01337     SPR_IMG_SAVE,            // TBN_SAVEGAME
    01338     SPR_IMG_SMALLMAP,        // TBN_SMALLMAP
    01339     SPR_IMG_TOWN,            // TBN_TOWNDIRECTORY
    01340     SPR_IMG_SUBSIDIES,       // TBN_SUBSIDIES
    01341     SPR_IMG_COMPANY_LIST,    // TBN_STATIONS
    01342     SPR_IMG_COMPANY_FINANCE, // TBN_FINANCES
    01343     SPR_IMG_COMPANY_GENERAL, // TBN_COMPANIES
    01344     SPR_IMG_GRAPHS,          // TBN_GRAPHICS
    01345     SPR_IMG_COMPANY_LEAGUE,  // TBN_LEAGUE
    01346     SPR_IMG_INDUSTRY,        // TBN_INDUSTRIES
    01347     SPR_IMG_TRAINLIST,       // TBN_TRAINS
    01348     SPR_IMG_TRUCKLIST,       // TBN_ROADVEHS
    01349     SPR_IMG_SHIPLIST,        // TBN_SHIPS
    01350     SPR_IMG_AIRPLANESLIST,   // TBN_AIRCRAFTS
    01351     SPR_IMG_ZOOMIN,          // TBN_ZOOMIN
    01352     SPR_IMG_ZOOMOUT,         // TBN_ZOOMOUT
    01353     SPR_IMG_BUILDRAIL,       // TBN_RAILS
    01354     SPR_IMG_BUILDROAD,       // TBN_ROADS
    01355     SPR_IMG_BUILDWATER,      // TBN_WATER
    01356     SPR_IMG_BUILDAIR,        // TBN_AIR
    01357     SPR_IMG_LANDSCAPING,     // TBN_LANDSCAPE
    01358     SPR_IMG_MUSIC,           // TBN_MUSICSOUND
    01359     SPR_IMG_MESSAGES,        // TBN_NEWSREPORT
    01360     SPR_IMG_QUERY,           // TBN_HELP
    01361     SPR_IMG_SWITCH_TOOLBAR,  // TBN_SWITCHBAR
    01362   };
    01363
    01364   NWidgetMainToolbarContainer *hor = new NWidgetMainToolbarContainer();
    01365   for (uint i = 0; i < TBN_END; i++) {
    01366     switch (i) {
    01367       case 4: case 8: case 13: case 17: case 19: case 24: hor->Add(new NWidgetSpacer(0, 0)); break;
    01368     }
    01369     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));
    01370   }
    01371
    01372   *biggest_index = max<int>(*biggest_index, TBN_SWITCHBAR);
    01373   return hor;
    01374 }
    01375
    01376 static const NWidgetPart _nested_toolbar_normal_widgets[] = {
    01377   NWidgetFunction(MakeMainToolbar),
    01378 };
    01379
    01380 static const WindowDesc _toolb_normal_desc(
    01381   WDP_MANUAL, 640, 22,
    01382   WC_MAIN_TOOLBAR, WC_NONE,
    01383   WDF_NO_FOCUS,
    01384   _nested_toolbar_normal_widgets, lengthof(_nested_toolbar_normal_widgets)
    01385 );
    01386
    01387
    01388 /* --- Toolbar handling for the scenario editor */
    01389
    01390 static ToolbarButtonProc * const _scen_toolbar_button_procs[] = {
    01391   ToolbarPauseClick,
    01392   ToolbarFastForwardClick,
    01393   ToolbarOptionsClick,
    01394   ToolbarScenSaveOrLoad,
    01395   ToolbarBtn_NULL,
    01396   ToolbarBtn_NULL,
    01397   ToolbarScenDateBackward,
    01398   ToolbarScenDateForward,
    01399   ToolbarScenMapTownDir,
    01400   ToolbarZoomInClick,
    01401   ToolbarZoomOutClick,
    01402   ToolbarScenGenLand,
    01403   ToolbarScenGenTown,
    01404   ToolbarScenGenIndustry,
    01405   ToolbarScenBuildRoad,
    01406   ToolbarScenBuildDocks,
    01407   ToolbarScenPlantTrees,
    01408   ToolbarScenPlaceSign,
    01409   ToolbarBtn_NULL,
    01410   NULL,
    01411   NULL,
    01412   NULL,
    01413   NULL,
    01414   NULL,
    01415   ToolbarMusicClick,
    01416   NULL,
    01417   ToolbarHelpClick,
    01418   ToolbarSwitchClick,
    01419 };
    01420
    01421 struct ScenarioEditorToolbarWindow : Window {
    01422 public:
    01423   ScenarioEditorToolbarWindow(const WindowDesc *desc) : Window()
    01424   {
    01425     this->InitNested(desc, 0);
    01426
    01427     CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
    01428     PositionMainToolbar(this);
    01429     DoZoomInOutWindow(ZOOM_NONE, this);
    01430   }
    01431
    01432   virtual void OnPaint()
    01433   {
    01434     this->SetWidgetDisabledState(TBSE_DATEBACKWARD, _settings_game.game_creation.starting_year <= MIN_YEAR);
    01435     this->SetWidgetDisabledState(TBSE_DATEFORWARD, _settings_game.game_creation.starting_year >= MAX_YEAR);
    01436
    01437     this->DrawWidgets();
    01438   }
    01439
    01440   virtual void DrawWidget(const Rect &r, int widget) const
    01441   {
    01442     switch (widget) {
    01443       case TBSE_DATEPANEL:
    01444         SetDParam(0, ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
    01445         DrawString(r.left, r.right, (this->height - FONT_HEIGHT_NORMAL) / 2, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_CENTER);
    01446         break;
    01447
    01448       case TBSE_SPACERPANEL: {
    01449         int height = r.bottom - r.top;
    01450         if (height > 2 * FONT_HEIGHT_NORMAL) {
    01451           DrawString(r.left, r.right, (height + 1) / 2 - FONT_HEIGHT_NORMAL, STR_SCENEDIT_TOOLBAR_OPENTTD, TC_FROMSTRING, SA_CENTER);
    01452           DrawString(r.left, r.right, (height + 1) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_CENTER);
    01453         } else {
    01454           DrawString(r.left, r.right, (height - FONT_HEIGHT_NORMAL) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_CENTER);
    01455         }
    01456       } break;
    01457     }
    01458   }
    01459
    01460   virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
    01461   {
    01462     switch (widget) {
    01463       case TBSE_SPACERPANEL:
    01464         size->width = max(GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_OPENTTD).width, GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR).width) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
    01465         break;
    01466
    01467       case TBSE_DATEPANEL:
    01468         SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1));
    01469         *size = GetStringBoundingBox(STR_WHITE_DATE_LONG);
    01470         size->height = max(size->height, GetSpriteSize(SPR_IMG_SAVE).height + WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM);
    01471         break;
    01472     }
    01473   }
    01474
    01475   virtual void OnClick(Point pt, int widget, int click_count)
    01476   {
    01477     if (_game_mode == GM_MENU) return;
    01478     _scen_toolbar_button_procs[widget](this);
    01479   }
    01480
    01481   virtual void OnDropdownSelect(int widget, int index)
    01482   {
    01483     /* The map button is in a different location on the scenario
    01484      * editor toolbar, so we need to adjust for it. */
    01485     if (widget == TBSE_SMALLMAP) widget = TBN_SMALLMAP;
    01486     _menu_clicked_procs[widget](index);
    01487     SndPlayFx(SND_15_BEEP);
    01488   }
    01489
    01490   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
    01491   {
    01492     switch (keycode) {
    01493       case WKC_F1: case WKC_PAUSE: ToolbarPauseClick(this); break;
    01494       case WKC_F2: ShowGameOptions(); break;
    01495       case WKC_F3: MenuClickSaveLoad(); break;
    01496       case WKC_F4: ToolbarScenGenLand(this); break;
    01497       case WKC_F5: ToolbarScenGenTown(this); break;
    01498       case WKC_F6: ToolbarScenGenIndustry(this); break;
    01499       case WKC_F7: ToolbarScenBuildRoad(this); break;
    01500       case WKC_F8: ToolbarScenBuildDocks(this); break;
    01501       case WKC_F9: ToolbarScenPlantTrees(this); break;
    01502       case WKC_F10: ToolbarScenPlaceSign(this); break;
    01503       case WKC_F11: ShowMusicWindow(); break;
    01504       case WKC_F12: PlaceLandBlockInfo(); break;
    01505       case WKC_CTRL | 'S': MenuClickSmallScreenshot(); break;
    01506       case WKC_CTRL | 'G': MenuClickWorldScreenshot(); break;
    01507
    01508       /* those following are all fall through */
    01509       case WKC_NUM_PLUS:
    01510       case WKC_EQUALS:
    01511       case WKC_SHIFT | WKC_EQUALS:
    01512       case WKC_SHIFT | WKC_F5: ToolbarZoomInClick(this); break;
    01513
    01514       /* those following are all fall through */
    01515       case WKC_NUM_MINUS:
    01516       case WKC_MINUS:
    01517       case WKC_SHIFT | WKC_MINUS:
    01518       case WKC_SHIFT | WKC_F6: ToolbarZoomOutClick(this); break;
    01519
    01520       case 'L': ShowEditorTerraformToolbar(); break;
    01521       case 'Q': case 'W': case 'E': case 'D': ShowEditorTerraformToolbarWithTool(key, keycode); break;
    01522       case 'M': ShowSmallMap(); break;
    01523       case 'V': ShowExtraViewPortWindow(); break;
    01524       default: return ES_NOT_HANDLED;
    01525     }
    01526     return ES_HANDLED;
    01527   }
    01528
    01529   virtual void OnPlaceObject(Point pt, TileIndex tile)
    01530   {
    01531     _place_proc(tile);
    01532   }
    01533
    01534   virtual void OnTimeout()
    01535   {
    01536     this->SetWidgetsLoweredState(false, TBSE_DATEBACKWARD, TBSE_DATEFORWARD, WIDGET_LIST_END);
    01537     this->SetWidgetDirty(TBSE_DATEBACKWARD);
    01538     this->SetWidgetDirty(TBSE_DATEFORWARD);
    01539   }
    01540
    01541   virtual void OnTick()
    01542   {
    01543     if (this->IsWidgetLowered(TBSE_PAUSE) != !!_pause_mode) {
    01544       this->ToggleWidgetLoweredState(TBSE_PAUSE);
    01545       this->SetDirty();
    01546     }
    01547
    01548     if (this->IsWidgetLowered(TBSE_FASTFORWARD) != !!_fast_forward) {
    01549       this->ToggleWidgetLoweredState(TBSE_FASTFORWARD);
    01550       this->SetDirty();
    01551     }
    01552   }
    01553
    01554   virtual void OnInvalidateData(int data)
    01555   {
    01556     if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, TBSE_ZOOMIN, TBSE_ZOOMOUT);
    01557   }
    01558 };
    01559
    01560 static const NWidgetPart _nested_toolb_scen_inner_widgets[] = {
    01561   NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_PAUSE), SetDataTip(SPR_IMG_PAUSE, STR_TOOLBAR_TOOLTIP_PAUSE_GAME),
    01562   NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_FASTFORWARD), SetDataTip(SPR_IMG_FASTFORWARD, STR_TOOLBAR_TOOLTIP_FORWARD),
    01563   NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_SETTINGS), SetDataTip(SPR_IMG_SETTINGS, STR_TOOLBAR_TOOLTIP_OPTIONS),
    01564   NWidget(WWT_IMGBTN_2, COLOUR_GREY, TBSE_SAVESCENARIO), SetDataTip(SPR_IMG_SAVE, STR_SCENEDIT_TOOLBAR_TOOLTIP_SAVE_SCENARIO_LOAD_SCENARIO),
    01565   NWidget(NWID_SPACER),
    01566   NWidget(WWT_PANEL, COLOUR_GREY, TBSE_SPACERPANEL), EndContainer(),
    01567   NWidget(NWID_SPACER),
    01568   NWidget(WWT_PANEL, COLOUR_GREY, TBSE_DATEPANEL_CONTAINER),
    01569     NWidget(NWID_HORIZONTAL), SetPIP(3, 2, 3),
    01570       NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_DATEBACKWARD), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD),
    01571       NWidget(WWT_EMPTY, COLOUR_GREY, TBSE_DATEPANEL),
    01572       NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_DATEFORWARD), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD),
    01573     EndContainer(),
    01574   EndContainer(),
    01575   NWidget(NWID_SPACER),
    01576   NWidget(WWT_IMGBTN, COLOUR_GREY, TBSE_SMALLMAP), SetDataTip(SPR_IMG_SMALLMAP, STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY),
    01577   NWidget(NWID_SPACER),
    01578   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_ZOOMIN), SetDataTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN),
    01579   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_ZOOMOUT), SetDataTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT),
    01580   NWidget(NWID_SPACER),
    01581   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_LANDGENERATE), SetDataTip(SPR_IMG_LANDSCAPING, STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION),
    01582   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_TOWNGENERATE), SetDataTip(SPR_IMG_TOWN, STR_SCENEDIT_TOOLBAR_TOWN_GENERATION),
    01583   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_INDUSTRYGENERATE), SetDataTip(SPR_IMG_INDUSTRY, STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION),
    01584   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_BUILDROAD), SetDataTip(SPR_IMG_BUILDROAD, STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION),
    01585   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_BUILDDOCKS), SetDataTip(SPR_IMG_BUILDWATER, STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS),
    01586   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_PLANTTREES), SetDataTip(SPR_IMG_PLANTTREES, STR_SCENEDIT_TOOLBAR_PLANT_TREES),
    01587   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TBSE_PLACESIGNS), SetDataTip(SPR_IMG_SIGN, STR_SCENEDIT_TOOLBAR_PLACE_SIGN),
    01588   NWidget(NWID_SPACER),
    01589   NWidget(WWT_IMGBTN, COLOUR_GREY, TBN_MUSICSOUND), SetDataTip(SPR_IMG_MUSIC, STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW),
    01590   NWidget(WWT_IMGBTN, COLOUR_GREY, TBN_HELP), SetDataTip(SPR_IMG_QUERY, STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION),
    01591   NWidget(WWT_IMGBTN, COLOUR_GREY, TBN_SWITCHBAR), SetDataTip(SPR_IMG_SWITCH_TOOLBAR, STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR),
    01592 };
    01593
    01594 static NWidgetBase *MakeScenarioToolbar(int *biggest_index)
    01595 {
    01596   return MakeNWidgets(_nested_toolb_scen_inner_widgets, lengthof(_nested_toolb_scen_inner_widgets), biggest_index, new NWidgetScenarioToolbarContainer());
    01597 }
    01598
    01599 static const NWidgetPart _nested_toolb_scen_widgets[] = {
    01600   NWidgetFunction(MakeScenarioToolbar),
    01601 };
    01602
    01603 static const WindowDesc _toolb_scen_desc(
    01604   WDP_MANUAL, 640, 22,
    01605   WC_MAIN_TOOLBAR, WC_NONE,
    01606   WDF_UNCLICK_BUTTONS | WDF_NO_FOCUS,
    01607   _nested_toolb_scen_widgets, lengthof(_nested_toolb_scen_widgets)
    01608 );
    01609
    01610 /* --- Allocating the toolbar --- */
    01611
    01612 void AllocateToolbar()
    01613 {
    01614   /* Clean old GUI values; railtype is (re)set by rail_gui.cpp */
    01615   _last_built_roadtype = ROADTYPE_ROAD;
    01616
    01617   if (_game_mode == GM_EDITOR) {
    01618     new ScenarioEditorToolbarWindow(&_toolb_scen_desc);
    01619   } else {
    01620     new MainToolbarWindow(&_toolb_normal_desc);
    01621   }
    01622 }