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,
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 }