# toolbar_gui.cpp

Go to the documentation of this file.

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