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 ? 12 : 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 
01003 void ToggleDirtyBlocks()
01004 {
01005   extern bool _draw_dirty_blocks;
01006   /* Always allow to toggle them off */
01007   if (_settings_client.gui.newgrf_developer_tools || _draw_dirty_blocks) {
01008     _draw_dirty_blocks = !_draw_dirty_blocks;
01009     MarkWholeScreenDirty();
01010   }
01011 }
01012 
01018 static CallBackFunction MenuClickHelp(int index)
01019 {
01020   switch (index) {
01021     case  0: return PlaceLandBlockInfo();
01022     case  2: IConsoleSwitch();                 break;
01023     case  3: ShowAIDebugWindow();              break;
01024     case  4: MenuClickSmallScreenshot();       break;
01025     case  5: MenuClickZoomedInScreenshot();    break;
01026     case  6: MenuClickDefaultZoomScreenshot(); break;
01027     case  7: MenuClickWorldScreenshot();       break;
01028     case  8: ShowAboutWindow();                break;
01029     case  9: ShowSpriteAlignerWindow();        break;
01030     case 10: ToggleBoundingBoxes();            break;
01031     case 11: ToggleDirtyBlocks();              break;
01032   }
01033   return CBF_NONE;
01034 }
01035 
01036 /* --- Switch toolbar button --- */
01037 
01038 static CallBackFunction ToolbarSwitchClick(Window *w)
01039 {
01040   if (_toolbar_mode != TB_LOWER) {
01041     _toolbar_mode = TB_LOWER;
01042   } else {
01043     _toolbar_mode = TB_UPPER;
01044   }
01045 
01046   w->ReInit();
01047   w->SetWidgetLoweredState(WID_TN_SWITCH_BAR, _toolbar_mode == TB_LOWER);
01048   SndPlayFx(SND_15_BEEP);
01049   return CBF_NONE;
01050 }
01051 
01052 /* --- Scenario editor specific handlers. */
01053 
01057 static CallBackFunction ToolbarScenDatePanel(Window *w)
01058 {
01059   SetDParam(0, _settings_game.game_creation.starting_year);
01060   ShowQueryString(STR_JUST_INT, STR_MAPGEN_START_DATE_QUERY_CAPT, 8, w, CS_NUMERAL, QSF_ENABLE_DEFAULT);
01061   _left_button_clicked = false;
01062   return CBF_NONE;
01063 }
01064 
01065 static CallBackFunction ToolbarScenDateBackward(Window *w)
01066 {
01067   /* don't allow too fast scrolling */
01068   if (!(w->flags & WF_TIMEOUT) || w->timeout_timer <= 1) {
01069     w->HandleButtonClick(WID_TE_DATE_BACKWARD);
01070     w->SetDirty();
01071 
01072     _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year - 1, MIN_YEAR, MAX_YEAR);
01073     SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
01074   }
01075   _left_button_clicked = false;
01076   return CBF_NONE;
01077 }
01078 
01079 static CallBackFunction ToolbarScenDateForward(Window *w)
01080 {
01081   /* don't allow too fast scrolling */
01082   if (!(w->flags & WF_TIMEOUT) || w->timeout_timer <= 1) {
01083     w->HandleButtonClick(WID_TE_DATE_FORWARD);
01084     w->SetDirty();
01085 
01086     _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year + 1, MIN_YEAR, MAX_YEAR);
01087     SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
01088   }
01089   _left_button_clicked = false;
01090   return CBF_NONE;
01091 }
01092 
01093 static CallBackFunction ToolbarScenGenLand(Window *w)
01094 {
01095   w->HandleButtonClick(WID_TE_LAND_GENERATE);
01096   SndPlayFx(SND_15_BEEP);
01097 
01098   ShowEditorTerraformToolbar();
01099   return CBF_NONE;
01100 }
01101 
01102 
01103 static CallBackFunction ToolbarScenGenTown(Window *w)
01104 {
01105   w->HandleButtonClick(WID_TE_TOWN_GENERATE);
01106   SndPlayFx(SND_15_BEEP);
01107   ShowFoundTownWindow();
01108   return CBF_NONE;
01109 }
01110 
01111 static CallBackFunction ToolbarScenGenIndustry(Window *w)
01112 {
01113   w->HandleButtonClick(WID_TE_INDUSTRY);
01114   SndPlayFx(SND_15_BEEP);
01115   ShowBuildIndustryWindow();
01116   return CBF_NONE;
01117 }
01118 
01119 static CallBackFunction ToolbarScenBuildRoad(Window *w)
01120 {
01121   w->HandleButtonClick(WID_TE_ROADS);
01122   SndPlayFx(SND_15_BEEP);
01123   ShowBuildRoadScenToolbar();
01124   return CBF_NONE;
01125 }
01126 
01127 static CallBackFunction ToolbarScenBuildDocks(Window *w)
01128 {
01129   w->HandleButtonClick(WID_TE_WATER);
01130   SndPlayFx(SND_15_BEEP);
01131   ShowBuildDocksScenToolbar();
01132   return CBF_NONE;
01133 }
01134 
01135 static CallBackFunction ToolbarScenPlantTrees(Window *w)
01136 {
01137   w->HandleButtonClick(WID_TE_TREES);
01138   SndPlayFx(SND_15_BEEP);
01139   ShowBuildTreesToolbar();
01140   return CBF_NONE;
01141 }
01142 
01143 static CallBackFunction ToolbarScenPlaceSign(Window *w)
01144 {
01145   w->HandleButtonClick(WID_TE_SIGNS);
01146   SndPlayFx(SND_15_BEEP);
01147   return SelectSignTool();
01148 }
01149 
01150 static CallBackFunction ToolbarBtn_NULL(Window *w)
01151 {
01152   return CBF_NONE;
01153 }
01154 
01155 typedef CallBackFunction MenuClickedProc(int index);
01156 
01157 static MenuClickedProc * const _menu_clicked_procs[] = {
01158   NULL,                 // 0
01159   NULL,                 // 1
01160   MenuClickSettings,    // 2
01161   MenuClickSaveLoad,    // 3
01162   MenuClickMap,         // 4
01163   MenuClickTown,        // 5
01164   MenuClickSubsidies,   // 6
01165   MenuClickStations,    // 7
01166   MenuClickFinances,    // 8
01167   MenuClickCompany,     // 9
01168   MenuClickGraphs,      // 10
01169   MenuClickLeague,      // 11
01170   MenuClickIndustry,    // 12
01171   MenuClickShowTrains,  // 13
01172   MenuClickShowRoad,    // 14
01173   MenuClickShowShips,   // 15
01174   MenuClickShowAir,     // 16
01175   MenuClickMap,         // 17
01176   NULL,                 // 18
01177   MenuClickBuildRail,   // 19
01178   MenuClickBuildRoad,   // 20
01179   MenuClickBuildWater,  // 21
01180   MenuClickBuildAir,    // 22
01181   MenuClickForest,      // 23
01182   MenuClickMusicWindow, // 24
01183   MenuClickNewspaper,   // 25
01184   MenuClickHelp,        // 26
01185 };
01186 
01187 int16 *_preferred_toolbar_size = NULL; 
01188 
01190 class NWidgetToolbarContainer : public NWidgetContainer {
01191   bool visible[WID_TN_END]; 
01192 protected:
01193   uint spacers;          
01194 
01195 public:
01196   NWidgetToolbarContainer() : NWidgetContainer(NWID_HORIZONTAL)
01197   {
01198   }
01199 
01205   bool IsButton(WidgetType type) const
01206   {
01207     return type == WWT_IMGBTN || type == WWT_IMGBTN_2 || type == WWT_PUSHIMGBTN;
01208   }
01209 
01210   void SetupSmallestSize(Window *w, bool init_array)
01211   {
01212     this->smallest_x = 0; // Biggest child
01213     this->smallest_y = 0; // Biggest child
01214     this->fill_x = 1;
01215     this->fill_y = 0;
01216     this->resize_x = 1; // We only resize in this direction
01217     this->resize_y = 0; // We never resize in this direction
01218     this->spacers = 0;
01219 
01220     uint nbuttons = 0;
01221     /* First initialise some variables... */
01222     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01223       child_wid->SetupSmallestSize(w, init_array);
01224       this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom);
01225       if (this->IsButton(child_wid->type)) {
01226         nbuttons++;
01227         this->smallest_x = max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right);
01228       } else if (child_wid->type == NWID_SPACER) {
01229         this->spacers++;
01230       }
01231     }
01232 
01233     /* ... then in a second pass make sure the 'current' heights are set. Won't change ever. */
01234     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01235       child_wid->current_y = this->smallest_y;
01236       if (!this->IsButton(child_wid->type)) {
01237         child_wid->current_x = child_wid->smallest_x;
01238       }
01239     }
01240     *_preferred_toolbar_size = nbuttons * this->smallest_x;
01241   }
01242 
01243   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl)
01244   {
01245     assert(given_width >= this->smallest_x && given_height >= this->smallest_y);
01246 
01247     this->pos_x = x;
01248     this->pos_y = y;
01249     this->current_x = given_width;
01250     this->current_y = given_height;
01251 
01252     /* Figure out what are the visible buttons */
01253     memset(this->visible, 0, sizeof(this->visible));
01254     uint arrangable_count, button_count, spacer_count;
01255     const byte *arrangement = GetButtonArrangement(given_width, arrangable_count, button_count, spacer_count);
01256     for (uint i = 0; i < arrangable_count; i++) {
01257       this->visible[arrangement[i]] = true;
01258     }
01259 
01260     /* Create us ourselves a quick lookup table */
01261     NWidgetBase *widgets[WID_TN_END];
01262     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01263       if (child_wid->type == NWID_SPACER) continue;
01264       widgets[((NWidgetCore*)child_wid)->index] = child_wid;
01265     }
01266 
01267     /* Now assign the widgets to their rightful place */
01268     uint position = 0; // Place to put next child relative to origin of the container.
01269     uint spacer_space = max(0, (int)given_width - (int)(button_count * this->smallest_x)); // Remaining spacing for 'spacer' widgets
01270     uint button_space = given_width - spacer_space; // Remaining spacing for the buttons
01271     uint spacer_i = 0;
01272     uint button_i = 0;
01273 
01274     /* Index into the arrangement indices. The macro lastof cannot be used here! */
01275     const byte *cur_wid = rtl ? &arrangement[arrangable_count - 1] : arrangement;
01276     for (uint i = 0; i < arrangable_count; i++) {
01277       NWidgetBase *child_wid = widgets[*cur_wid];
01278       /* If we have to give space to the spacers, do that */
01279       if (spacer_space != 0) {
01280         NWidgetBase *possible_spacer = rtl ? child_wid->next : child_wid->prev;
01281         if (possible_spacer != NULL && possible_spacer->type == NWID_SPACER) {
01282           uint add = spacer_space / (spacer_count - spacer_i);
01283           position += add;
01284           spacer_space -= add;
01285           spacer_i++;
01286         }
01287       }
01288 
01289       /* Buttons can be scaled, the others not. */
01290       if (this->IsButton(child_wid->type)) {
01291         child_wid->current_x = button_space / (button_count - button_i);
01292         button_space -= child_wid->current_x;
01293         button_i++;
01294       }
01295       child_wid->AssignSizePosition(sizing, x + position, y, child_wid->current_x, this->current_y, rtl);
01296       position += child_wid->current_x;
01297 
01298       if (rtl) {
01299         cur_wid--;
01300       } else {
01301         cur_wid++;
01302       }
01303     }
01304   }
01305 
01306   /* virtual */ void Draw(const Window *w)
01307   {
01308     /* Draw brown-red toolbar bg. */
01309     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);
01310     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);
01311 
01312     bool rtl = _current_text_dir == TD_RTL;
01313     for (NWidgetBase *child_wid = rtl ? this->tail : this->head; child_wid != NULL; child_wid = rtl ? child_wid->prev : child_wid->next) {
01314       if (child_wid->type == NWID_SPACER) continue;
01315       if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
01316 
01317       child_wid->Draw(w);
01318     }
01319   }
01320 
01321   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y)
01322   {
01323     if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL;
01324 
01325     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01326       if (child_wid->type == NWID_SPACER) continue;
01327       if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
01328 
01329       NWidgetCore *nwid = child_wid->GetWidgetFromPos(x, y);
01330       if (nwid != NULL) return nwid;
01331     }
01332     return NULL;
01333   }
01334 
01343   virtual const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const = 0;
01344 };
01345 
01347 class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
01348   /* virtual */ const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
01349   {
01350     static const uint SMALLEST_ARRANGEMENT = 14;
01351     static const uint BIGGEST_ARRANGEMENT  = 19;
01352     static const byte arrange14[] = {
01353       0,  1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 27,
01354       2,  3,  4,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 27,
01355     };
01356     static const byte arrange15[] = {
01357       0,  1,  4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
01358       0,  2,  4,  3,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 27,
01359     };
01360     static const byte arrange16[] = {
01361       0,  1,  2,  4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
01362       0,  1,  3,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 17, 18, 27,
01363     };
01364     static const byte arrange17[] = {
01365       0,  1,  2,  4,  6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
01366       0,  1,  3,  4,  6,  5,  7,  8,  9, 10, 12, 24, 25, 26, 17, 18, 27,
01367     };
01368     static const byte arrange18[] = {
01369       0,  1,  2,  4,  5,  6,  7,  8,  9, 12, 19, 20, 21, 22, 23, 17, 18, 27,
01370       0,  1,  3,  4,  5,  6,  7, 10, 13, 14, 15, 16, 24, 25, 26, 17, 18, 27,
01371     };
01372     static const byte arrange19[] = {
01373       0,  1,  2,  4,  5,  6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 27,
01374       0,  1,  3,  4,  7,  8,  9, 10, 12, 25, 19, 20, 21, 22, 23, 26, 17, 18, 27,
01375     };
01376     static const byte arrange_all[] = {
01377       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,
01378     };
01379 
01380     /* If at least BIGGEST_ARRANGEMENT fit, just spread all the buttons nicely */
01381     uint full_buttons = max(CeilDiv(width, this->smallest_x), SMALLEST_ARRANGEMENT);
01382     if (full_buttons > BIGGEST_ARRANGEMENT) {
01383       button_count = arrangable_count = lengthof(arrange_all);
01384       spacer_count = this->spacers;
01385       return arrange_all;
01386     }
01387 
01388     /* Introduce the split toolbar */
01389     static const byte * const arrangements[] = { arrange14, arrange15, arrange16, arrange17, arrange18, arrange19 };
01390 
01391     button_count = arrangable_count = full_buttons;
01392     spacer_count = this->spacers;
01393     return arrangements[full_buttons - SMALLEST_ARRANGEMENT] + ((_toolbar_mode == TB_LOWER) ? full_buttons : 0);
01394   }
01395 };
01396 
01398 class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer {
01399   uint panel_widths[2]; 
01400 
01401   void SetupSmallestSize(Window *w, bool init_array)
01402   {
01403     this->NWidgetToolbarContainer::SetupSmallestSize(w, init_array);
01404 
01405     /* Find the size of panel_widths */
01406     uint i = 0;
01407     for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01408       if (child_wid->type == NWID_SPACER || this->IsButton(child_wid->type)) continue;
01409 
01410       assert(i < lengthof(this->panel_widths));
01411       this->panel_widths[i++] = child_wid->current_x;
01412       *_preferred_toolbar_size += child_wid->current_x;
01413     }
01414   }
01415 
01416   /* virtual */ const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
01417   {
01418     static const byte arrange_all[] = {
01419       0, 1, 2, 3, 4, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24, 26,
01420     };
01421     static const byte arrange_nopanel[] = {
01422       0, 1, 2, 3, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24, 26,
01423     };
01424     static const byte arrange_switch[] = {
01425       18,  8, 11, 12, 13, 14, 15, 16, 17, 27,
01426        0,  1,  2,  3, 18,  9, 10, 24, 26, 27,
01427     };
01428 
01429     /* If we can place all buttons *and* the panels, show them. */
01430     uint min_full_width = (lengthof(arrange_all) - lengthof(this->panel_widths)) * this->smallest_x + this->panel_widths[0] + this->panel_widths[1];
01431     if (width >= min_full_width) {
01432       width -= this->panel_widths[0] + this->panel_widths[1];
01433       arrangable_count = lengthof(arrange_all);
01434       button_count = arrangable_count - 2;
01435       spacer_count = this->spacers;
01436       return arrange_all;
01437     }
01438 
01439     /* 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 */
01440     uint min_small_width = (lengthof(arrange_switch) - lengthof(this->panel_widths)) * this->smallest_x / 2 + this->panel_widths[1];
01441     if (width > min_small_width) {
01442       width -= this->panel_widths[1];
01443       arrangable_count = lengthof(arrange_nopanel);
01444       button_count = arrangable_count - 1;
01445       spacer_count = this->spacers - 1;
01446       return arrange_nopanel;
01447     }
01448 
01449     /* Split toolbar */
01450     width -= this->panel_widths[1];
01451     arrangable_count = lengthof(arrange_switch) / 2;
01452     button_count = arrangable_count - 1;
01453     spacer_count = 0;
01454     return arrange_switch + ((_toolbar_mode == TB_LOWER) ? arrangable_count : 0);
01455   }
01456 };
01457 
01458 /* --- Toolbar handling for the 'normal' case */
01459 
01460 typedef CallBackFunction ToolbarButtonProc(Window *w);
01461 
01462 static ToolbarButtonProc * const _toolbar_button_procs[] = {
01463   ToolbarPauseClick,
01464   ToolbarFastForwardClick,
01465   ToolbarOptionsClick,
01466   ToolbarSaveClick,
01467   ToolbarMapClick,
01468   ToolbarTownClick,
01469   ToolbarSubsidiesClick,
01470   ToolbarStationsClick,
01471   ToolbarFinancesClick,
01472   ToolbarCompaniesClick,
01473   ToolbarGraphsClick,
01474   ToolbarLeagueClick,
01475   ToolbarIndustryClick,
01476   ToolbarTrainClick,
01477   ToolbarRoadClick,
01478   ToolbarShipClick,
01479   ToolbarAirClick,
01480   ToolbarZoomInClick,
01481   ToolbarZoomOutClick,
01482   ToolbarBuildRailClick,
01483   ToolbarBuildRoadClick,
01484   ToolbarBuildWaterClick,
01485   ToolbarBuildAirClick,
01486   ToolbarForestClick,
01487   ToolbarMusicClick,
01488   ToolbarNewspaperClick,
01489   ToolbarHelpClick,
01490   ToolbarSwitchClick,
01491 };
01492 
01493 enum MainToolbarHotkeys {
01494   MTHK_PAUSE,
01495   MTHK_FASTFORWARD,
01496   MTHK_SETTINGS,
01497   MTHK_SAVEGAME,
01498   MTHK_LOADGAME,
01499   MTHK_SMALLMAP,
01500   MTHK_TOWNDIRECTORY,
01501   MTHK_SUBSIDIES,
01502   MTHK_STATIONS,
01503   MTHK_FINANCES,
01504   MTHK_COMPANIES,
01505   MTHK_GRAPHS,
01506   MTHK_LEAGUE,
01507   MTHK_INDUSTRIES,
01508   MTHK_TRAIN_LIST,
01509   MTHK_ROADVEH_LIST,
01510   MTHK_SHIP_LIST,
01511   MTHK_AIRCRAFT_LIST,
01512   MTHK_ZOOM_IN,
01513   MTHK_ZOOM_OUT,
01514   MTHK_BUILD_RAIL,
01515   MTHK_BUILD_ROAD,
01516   MTHK_BUILD_DOCKS,
01517   MTHK_BUILD_AIRPORT,
01518   MTHK_BUILD_TREES,
01519   MTHK_MUSIC,
01520   MTHK_AI_DEBUG,
01521   MTHK_SMALL_SCREENSHOT,
01522   MTHK_ZOOMEDIN_SCREENSHOT,
01523   MTHK_DEFAULTZOOM_SCREENSHOT,
01524   MTHK_GIANT_SCREENSHOT,
01525   MTHK_CHEATS,
01526   MTHK_TERRAFORM,
01527   MTHK_EXTRA_VIEWPORT,
01528   MTHK_CLIENT_LIST,
01529   MTHK_SIGN_LIST,
01530 };
01531 
01533 struct MainToolbarWindow : Window {
01534   CallBackFunction last_started_action; 
01535 
01536   MainToolbarWindow(const WindowDesc *desc) : Window()
01537   {
01538     this->InitNested(desc, 0);
01539 
01540     this->last_started_action = CBF_NONE;
01541     CLRBITS(this->flags, WF_WHITE_BORDER);
01542     this->SetWidgetDisabledState(WID_TN_PAUSE, _networking && !_network_server); // if not server, disable pause button
01543     this->SetWidgetDisabledState(WID_TN_FAST_FORWARD, _networking); // if networking, disable fast-forward button
01544     PositionMainToolbar(this);
01545     DoZoomInOutWindow(ZOOM_NONE, this);
01546   }
01547 
01548   virtual void OnPaint()
01549   {
01550     /* If spectator, disable all construction buttons
01551      * ie : Build road, rail, ships, airports and landscaping
01552      * Since enabled state is the default, just disable when needed */
01553     this->SetWidgetsDisabledState(_local_company == COMPANY_SPECTATOR, WID_TN_RAILS, WID_TN_ROADS, WID_TN_WATER, WID_TN_AIR, WID_TN_LANDSCAPE, WIDGET_LIST_END);
01554     /* disable company list drop downs, if there are no companies */
01555     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);
01556 
01557     this->SetWidgetDisabledState(WID_TN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN));
01558     this->SetWidgetDisabledState(WID_TN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT));
01559 
01560     this->DrawWidgets();
01561   }
01562 
01563   virtual void OnClick(Point pt, int widget, int click_count)
01564   {
01565     if (_game_mode != GM_MENU && !this->IsWidgetDisabled(widget)) _toolbar_button_procs[widget](this);
01566   }
01567 
01568   virtual void OnDropdownSelect(int widget, int index)
01569   {
01570     CallBackFunction cbf = _menu_clicked_procs[widget](index);
01571     if (cbf != CBF_NONE) this->last_started_action = cbf;
01572   }
01573 
01574   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
01575   {
01576     switch (CheckHotkeyMatch(maintoolbar_hotkeys, keycode, this)) {
01577       case MTHK_PAUSE: ToolbarPauseClick(this); break;
01578       case MTHK_FASTFORWARD: ToolbarFastForwardClick(this); break;
01579       case MTHK_SETTINGS: ShowGameOptions(); break;
01580       case MTHK_SAVEGAME: MenuClickSaveLoad(); break;
01581       case MTHK_LOADGAME: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
01582       case MTHK_SMALLMAP: ShowSmallMap(); break;
01583       case MTHK_TOWNDIRECTORY: ShowTownDirectory(); break;
01584       case MTHK_SUBSIDIES: ShowSubsidiesList(); break;
01585       case MTHK_STATIONS: ShowCompanyStations(_local_company); break;
01586       case MTHK_FINANCES: ShowCompanyFinances(_local_company); break;
01587       case MTHK_COMPANIES: ShowCompany(_local_company); break;
01588       case MTHK_GRAPHS: ShowOperatingProfitGraph(); break;
01589       case MTHK_LEAGUE: ShowCompanyLeagueTable(); break;
01590       case MTHK_INDUSTRIES: ShowBuildIndustryWindow(); break;
01591       case MTHK_TRAIN_LIST: ShowVehicleListWindow(_local_company, VEH_TRAIN); break;
01592       case MTHK_ROADVEH_LIST: ShowVehicleListWindow(_local_company, VEH_ROAD); break;
01593       case MTHK_SHIP_LIST: ShowVehicleListWindow(_local_company, VEH_SHIP); break;
01594       case MTHK_AIRCRAFT_LIST: ShowVehicleListWindow(_local_company, VEH_AIRCRAFT); break;
01595       case MTHK_ZOOM_IN: ToolbarZoomInClick(this); break;
01596       case MTHK_ZOOM_OUT: ToolbarZoomOutClick(this); break;
01597       case MTHK_BUILD_RAIL: if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype); break;
01598       case MTHK_BUILD_ROAD: ShowBuildRoadToolbar(_last_built_roadtype); break;
01599       case MTHK_BUILD_DOCKS: ShowBuildDocksToolbar(); break;
01600       case MTHK_BUILD_AIRPORT: if (CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) ShowBuildAirToolbar(); break;
01601       case MTHK_BUILD_TREES: ShowBuildTreesToolbar(); break;
01602       case MTHK_MUSIC: ShowMusicWindow(); break;
01603       case MTHK_AI_DEBUG: ShowAIDebugWindow(); break;
01604       case MTHK_SMALL_SCREENSHOT: MenuClickSmallScreenshot(); break;
01605       case MTHK_ZOOMEDIN_SCREENSHOT: MenuClickZoomedInScreenshot(); break;
01606       case MTHK_DEFAULTZOOM_SCREENSHOT: MenuClickDefaultZoomScreenshot(); break;
01607       case MTHK_GIANT_SCREENSHOT: MenuClickWorldScreenshot(); break;
01608       case MTHK_CHEATS: if (!_networking) ShowCheatWindow(); break;
01609       case MTHK_TERRAFORM: ShowTerraformToolbar(); break;
01610       case MTHK_EXTRA_VIEWPORT: ShowExtraViewPortWindowForTileUnderCursor(); break;
01611 #ifdef ENABLE_NETWORK
01612       case MTHK_CLIENT_LIST: if (_networking) ShowClientList(); break;
01613 #endif
01614       case MTHK_SIGN_LIST: ShowSignList(); break;
01615       default: return ES_NOT_HANDLED;
01616     }
01617     return ES_HANDLED;
01618   }
01619 
01620   virtual void OnPlaceObject(Point pt, TileIndex tile)
01621   {
01622     switch (this->last_started_action) {
01623       case CBF_PLACE_SIGN:
01624         PlaceProc_Sign(tile);
01625         break;
01626 
01627       case CBF_PLACE_LANDINFO:
01628         ShowLandInfo(tile);
01629         break;
01630 
01631       default: NOT_REACHED();
01632     }
01633   }
01634 
01635   virtual void OnTick()
01636   {
01637     if (this->IsWidgetLowered(WID_TN_PAUSE) != !!_pause_mode) {
01638       this->ToggleWidgetLoweredState(WID_TN_PAUSE);
01639       this->SetWidgetDirty(WID_TN_PAUSE);
01640     }
01641 
01642     if (this->IsWidgetLowered(WID_TN_FAST_FORWARD) != !!_fast_forward) {
01643       this->ToggleWidgetLoweredState(WID_TN_FAST_FORWARD);
01644       this->SetWidgetDirty(WID_TN_FAST_FORWARD);
01645     }
01646   }
01647 
01648   virtual void OnTimeout()
01649   {
01650     /* We do not want to automatically raise the pause, fast forward and
01651      * switchbar buttons; they have to stay down when pressed etc. */
01652     for (uint i = WID_TN_SETTINGS; i < WID_TN_SWITCH_BAR; i++) {
01653       if (this->IsWidgetLowered(i)) {
01654         this->RaiseWidget(i);
01655         this->SetWidgetDirty(i);
01656       }
01657     }
01658   }
01659 
01665   virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
01666   {
01667     if (!gui_scope) return;
01668     if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TN_ZOOM_IN, WID_TN_ZOOM_OUT);
01669   }
01670 
01671   static Hotkey<MainToolbarWindow> maintoolbar_hotkeys[];
01672 };
01673 
01674 const uint16 _maintoolbar_pause_keys[] = {WKC_F1, WKC_PAUSE, 0};
01675 const uint16 _maintoolbar_zoomin_keys[] = {WKC_NUM_PLUS, WKC_EQUALS, WKC_SHIFT | WKC_EQUALS, WKC_SHIFT | WKC_F5, 0};
01676 const uint16 _maintoolbar_zoomout_keys[] = {WKC_NUM_MINUS, WKC_MINUS, WKC_SHIFT | WKC_MINUS, WKC_SHIFT | WKC_F6, 0};
01677 const uint16 _maintoolbar_smallmap_keys[] = {WKC_F4, 'M', 0};
01678 
01679 Hotkey<MainToolbarWindow> MainToolbarWindow::maintoolbar_hotkeys[] = {
01680   Hotkey<MainToolbarWindow>(_maintoolbar_pause_keys, "pause", MTHK_PAUSE),
01681   Hotkey<MainToolbarWindow>((uint16)0, "fastforward", MTHK_FASTFORWARD),
01682   Hotkey<MainToolbarWindow>(WKC_F2, "settings", MTHK_SETTINGS),
01683   Hotkey<MainToolbarWindow>(WKC_F3, "saveload", MTHK_SAVEGAME),
01684   Hotkey<MainToolbarWindow>((uint16)0, "load_game", MTHK_LOADGAME),
01685   Hotkey<MainToolbarWindow>(_maintoolbar_smallmap_keys, "smallmap", MTHK_SMALLMAP),
01686   Hotkey<MainToolbarWindow>(WKC_F5, "town_list", MTHK_TOWNDIRECTORY),
01687   Hotkey<MainToolbarWindow>(WKC_F6, "subsidies", MTHK_SUBSIDIES),
01688   Hotkey<MainToolbarWindow>(WKC_F7, "station_list", MTHK_STATIONS),
01689   Hotkey<MainToolbarWindow>(WKC_F8, "finances", MTHK_FINANCES),
01690   Hotkey<MainToolbarWindow>(WKC_F9, "companies", MTHK_COMPANIES),
01691   Hotkey<MainToolbarWindow>(WKC_F10, "graphs", MTHK_GRAPHS),
01692   Hotkey<MainToolbarWindow>(WKC_F11, "league", MTHK_LEAGUE),
01693   Hotkey<MainToolbarWindow>(WKC_F12, "industry_list", MTHK_INDUSTRIES),
01694   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F1, "train_list", MTHK_TRAIN_LIST),
01695   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F2, "roadveh_list", MTHK_ROADVEH_LIST),
01696   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F3, "ship_list", MTHK_SHIP_LIST),
01697   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F4, "aircraft_list", MTHK_AIRCRAFT_LIST),
01698   Hotkey<MainToolbarWindow>(_maintoolbar_zoomin_keys, "zoomin", MTHK_ZOOM_IN),
01699   Hotkey<MainToolbarWindow>(_maintoolbar_zoomout_keys, "zoomout", MTHK_ZOOM_OUT),
01700   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F7, "build_rail", MTHK_BUILD_RAIL),
01701   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F8, "build_road", MTHK_BUILD_ROAD),
01702   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F9, "build_docks", MTHK_BUILD_DOCKS),
01703   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F10, "build_airport", MTHK_BUILD_AIRPORT),
01704   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F11, "build_trees", MTHK_BUILD_TREES),
01705   Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F12, "music", MTHK_MUSIC),
01706   Hotkey<MainToolbarWindow>((uint16)0, "ai_debug", MTHK_AI_DEBUG),
01707   Hotkey<MainToolbarWindow>(WKC_CTRL  | 'S', "small_screenshot", MTHK_SMALL_SCREENSHOT),
01708   Hotkey<MainToolbarWindow>(WKC_CTRL  | 'P', "zoomedin_screenshot", MTHK_ZOOMEDIN_SCREENSHOT),
01709   Hotkey<MainToolbarWindow>(WKC_CTRL  | 'D', "defaultzoom_screenshot", MTHK_DEFAULTZOOM_SCREENSHOT),
01710   Hotkey<MainToolbarWindow>((uint16)0, "giant_screenshot", MTHK_GIANT_SCREENSHOT),
01711   Hotkey<MainToolbarWindow>(WKC_CTRL | WKC_ALT | 'C', "cheats", MTHK_CHEATS),
01712   Hotkey<MainToolbarWindow>('L', "terraform", MTHK_TERRAFORM),
01713   Hotkey<MainToolbarWindow>('V', "extra_viewport", MTHK_EXTRA_VIEWPORT),
01714 #ifdef ENABLE_NETWORK
01715   Hotkey<MainToolbarWindow>((uint16)0, "client_list", MTHK_CLIENT_LIST),
01716 #endif
01717   Hotkey<MainToolbarWindow>((uint16)0, "sign_list", MTHK_SIGN_LIST),
01718   HOTKEY_LIST_END(MainToolbarWindow)
01719 };
01720 Hotkey<MainToolbarWindow> *_maintoolbar_hotkeys = MainToolbarWindow::maintoolbar_hotkeys;
01721 
01722 static NWidgetBase *MakeMainToolbar(int *biggest_index)
01723 {
01725   static const SpriteID toolbar_button_sprites[] = {
01726     SPR_IMG_PAUSE,           // WID_TN_PAUSE
01727     SPR_IMG_FASTFORWARD,     // WID_TN_FAST_FORWARD
01728     SPR_IMG_SETTINGS,        // WID_TN_SETTINGS
01729     SPR_IMG_SAVE,            // WID_TN_SAVE
01730     SPR_IMG_SMALLMAP,        // WID_TN_SMALL_MAP
01731     SPR_IMG_TOWN,            // WID_TN_TOWNS
01732     SPR_IMG_SUBSIDIES,       // WID_TN_SUBSIDIES
01733     SPR_IMG_COMPANY_LIST,    // WID_TN_STATIONS
01734     SPR_IMG_COMPANY_FINANCE, // WID_TN_FINANCES
01735     SPR_IMG_COMPANY_GENERAL, // WID_TN_COMPANIES
01736     SPR_IMG_GRAPHS,          // WID_TN_GRAPHS
01737     SPR_IMG_COMPANY_LEAGUE,  // WID_TN_LEAGUE
01738     SPR_IMG_INDUSTRY,        // WID_TN_INDUSTRIES
01739     SPR_IMG_TRAINLIST,       // WID_TN_TRAINS
01740     SPR_IMG_TRUCKLIST,       // WID_TN_ROADVEHS
01741     SPR_IMG_SHIPLIST,        // WID_TN_SHIPS
01742     SPR_IMG_AIRPLANESLIST,   // WID_TN_AIRCRAFT
01743     SPR_IMG_ZOOMIN,          // WID_TN_ZOOMIN
01744     SPR_IMG_ZOOMOUT,         // WID_TN_ZOOMOUT
01745     SPR_IMG_BUILDRAIL,       // WID_TN_RAILS
01746     SPR_IMG_BUILDROAD,       // WID_TN_ROADS
01747     SPR_IMG_BUILDWATER,      // WID_TN_WATER
01748     SPR_IMG_BUILDAIR,        // WID_TN_AIR
01749     SPR_IMG_LANDSCAPING,     // WID_TN_LANDSCAPE
01750     SPR_IMG_MUSIC,           // WID_TN_MUSIC_SOUND
01751     SPR_IMG_MESSAGES,        // WID_TN_MESSAGES
01752     SPR_IMG_QUERY,           // WID_TN_HELP
01753     SPR_IMG_SWITCH_TOOLBAR,  // WID_TN_SWITCH_BAR
01754   };
01755 
01756   NWidgetMainToolbarContainer *hor = new NWidgetMainToolbarContainer();
01757   for (uint i = 0; i < WID_TN_END; i++) {
01758     switch (i) {
01759       case 4: case 8: case 13: case 17: case 19: case 24: hor->Add(new NWidgetSpacer(0, 0)); break;
01760     }
01761     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));
01762   }
01763 
01764   *biggest_index = max<int>(*biggest_index, WID_TN_SWITCH_BAR);
01765   return hor;
01766 }
01767 
01768 static const NWidgetPart _nested_toolbar_normal_widgets[] = {
01769   NWidgetFunction(MakeMainToolbar),
01770 };
01771 
01772 static WindowDesc _toolb_normal_desc(
01773   WDP_MANUAL, 640, 22,
01774   WC_MAIN_TOOLBAR, WC_NONE,
01775   WDF_NO_FOCUS,
01776   _nested_toolbar_normal_widgets, lengthof(_nested_toolbar_normal_widgets)
01777 );
01778 
01779 
01780 /* --- Toolbar handling for the scenario editor */
01781 
01782 static ToolbarButtonProc * const _scen_toolbar_button_procs[] = {
01783   ToolbarPauseClick,
01784   ToolbarFastForwardClick,
01785   ToolbarOptionsClick,
01786   ToolbarScenSaveOrLoad,
01787   ToolbarBtn_NULL,
01788   ToolbarScenDatePanel,
01789   ToolbarScenDateBackward,
01790   ToolbarScenDateForward,
01791   ToolbarScenMapTownDir,
01792   ToolbarZoomInClick,
01793   ToolbarZoomOutClick,
01794   ToolbarScenGenLand,
01795   ToolbarScenGenTown,
01796   ToolbarScenGenIndustry,
01797   ToolbarScenBuildRoad,
01798   ToolbarScenBuildDocks,
01799   ToolbarScenPlantTrees,
01800   ToolbarScenPlaceSign,
01801   ToolbarBtn_NULL,
01802   NULL,
01803   NULL,
01804   NULL,
01805   NULL,
01806   NULL,
01807   ToolbarMusicClick,
01808   NULL,
01809   ToolbarHelpClick,
01810   ToolbarSwitchClick,
01811 };
01812 
01813 enum MainToolbarEditorHotkeys {
01814   MTEHK_PAUSE,
01815   MTEHK_FASTFORWARD,
01816   MTEHK_SETTINGS,
01817   MTEHK_SAVEGAME,
01818   MTEHK_GENLAND,
01819   MTEHK_GENTOWN,
01820   MTEHK_GENINDUSTRY,
01821   MTEHK_BUILD_ROAD,
01822   MTEHK_BUILD_DOCKS,
01823   MTEHK_BUILD_TREES,
01824   MTEHK_SIGN,
01825   MTEHK_MUSIC,
01826   MTEHK_LANDINFO,
01827   MTEHK_SMALL_SCREENSHOT,
01828   MTEHK_ZOOMEDIN_SCREENSHOT,
01829   MTEHK_DEFAULTZOOM_SCREENSHOT,
01830   MTEHK_GIANT_SCREENSHOT,
01831   MTEHK_ZOOM_IN,
01832   MTEHK_ZOOM_OUT,
01833   MTEHK_TERRAFORM,
01834   MTEHK_SMALLMAP,
01835   MTEHK_EXTRA_VIEWPORT,
01836 };
01837 
01838 struct ScenarioEditorToolbarWindow : Window {
01839   CallBackFunction last_started_action; 
01840 
01841   ScenarioEditorToolbarWindow(const WindowDesc *desc) : Window()
01842   {
01843     this->InitNested(desc, 0);
01844 
01845     this->last_started_action = CBF_NONE;
01846     CLRBITS(this->flags, WF_WHITE_BORDER);
01847     PositionMainToolbar(this);
01848     DoZoomInOutWindow(ZOOM_NONE, this);
01849   }
01850 
01851   virtual void OnPaint()
01852   {
01853     this->SetWidgetDisabledState(WID_TE_DATE_BACKWARD, _settings_game.game_creation.starting_year <= MIN_YEAR);
01854     this->SetWidgetDisabledState(WID_TE_DATE_FORWARD, _settings_game.game_creation.starting_year >= MAX_YEAR);
01855 
01856     this->DrawWidgets();
01857   }
01858 
01859   virtual void DrawWidget(const Rect &r, int widget) const
01860   {
01861     switch (widget) {
01862       case WID_TE_DATE:
01863         SetDParam(0, ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
01864         DrawString(r.left, r.right, (this->height - FONT_HEIGHT_NORMAL) / 2, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_HOR_CENTER);
01865         break;
01866 
01867       case WID_TE_SPACER: {
01868         int height = r.bottom - r.top;
01869         if (height > 2 * FONT_HEIGHT_NORMAL) {
01870           DrawString(r.left, r.right, (height + 1) / 2 - FONT_HEIGHT_NORMAL, STR_SCENEDIT_TOOLBAR_OPENTTD, TC_FROMSTRING, SA_HOR_CENTER);
01871           DrawString(r.left, r.right, (height + 1) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER);
01872         } else {
01873           DrawString(r.left, r.right, (height - FONT_HEIGHT_NORMAL) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER);
01874         }
01875         break;
01876       }
01877     }
01878   }
01879 
01880   virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
01881   {
01882     switch (widget) {
01883       case WID_TE_SPACER:
01884         size->width = max(GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_OPENTTD).width, GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR).width) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
01885         break;
01886 
01887       case WID_TE_DATE:
01888         SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1));
01889         *size = GetStringBoundingBox(STR_WHITE_DATE_LONG);
01890         size->height = max(size->height, GetSpriteSize(SPR_IMG_SAVE).height + WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM);
01891         break;
01892     }
01893   }
01894 
01895   virtual void OnClick(Point pt, int widget, int click_count)
01896   {
01897     if (_game_mode == GM_MENU) return;
01898     CallBackFunction cbf = _scen_toolbar_button_procs[widget](this);
01899     if (cbf != CBF_NONE) this->last_started_action = cbf;
01900   }
01901 
01902   virtual void OnDropdownSelect(int widget, int index)
01903   {
01904     /* The map button is in a different location on the scenario
01905      * editor toolbar, so we need to adjust for it. */
01906     if (widget == WID_TE_SMALL_MAP) widget = WID_TN_SMALL_MAP;
01907     CallBackFunction cbf = _menu_clicked_procs[widget](index);
01908     if (cbf != CBF_NONE) this->last_started_action = cbf;
01909     SndPlayFx(SND_15_BEEP);
01910   }
01911 
01912   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
01913   {
01914     CallBackFunction cbf = CBF_NONE;
01915     switch (CheckHotkeyMatch(scenedit_maintoolbar_hotkeys, keycode, this)) {
01916       case MTEHK_PAUSE:                  ToolbarPauseClick(this); break;
01917       case MTEHK_FASTFORWARD:            ToolbarFastForwardClick(this); break;
01918       case MTEHK_SETTINGS:               ShowGameOptions(); break;
01919       case MTEHK_SAVEGAME:               MenuClickSaveLoad(); break;
01920       case MTEHK_GENLAND:                ToolbarScenGenLand(this); break;
01921       case MTEHK_GENTOWN:                ToolbarScenGenTown(this); break;
01922       case MTEHK_GENINDUSTRY:            ToolbarScenGenIndustry(this); break;
01923       case MTEHK_BUILD_ROAD:             ToolbarScenBuildRoad(this); break;
01924       case MTEHK_BUILD_DOCKS:            ToolbarScenBuildDocks(this); break;
01925       case MTEHK_BUILD_TREES:            ToolbarScenPlantTrees(this); break;
01926       case MTEHK_SIGN:                   cbf = ToolbarScenPlaceSign(this); break;
01927       case MTEHK_MUSIC:                  ShowMusicWindow(); break;
01928       case MTEHK_LANDINFO:               cbf = PlaceLandBlockInfo(); break;
01929       case MTEHK_SMALL_SCREENSHOT:       MenuClickSmallScreenshot(); break;
01930       case MTEHK_ZOOMEDIN_SCREENSHOT:    MenuClickZoomedInScreenshot(); break;
01931       case MTEHK_DEFAULTZOOM_SCREENSHOT: MenuClickDefaultZoomScreenshot(); break;
01932       case MTEHK_GIANT_SCREENSHOT:       MenuClickWorldScreenshot(); break;
01933       case MTEHK_ZOOM_IN:                ToolbarZoomInClick(this); break;
01934       case MTEHK_ZOOM_OUT:               ToolbarZoomOutClick(this); break;
01935       case MTEHK_TERRAFORM:              ShowEditorTerraformToolbar(); break;
01936       case MTEHK_SMALLMAP:               ShowSmallMap(); break;
01937       case MTEHK_EXTRA_VIEWPORT:         ShowExtraViewPortWindowForTileUnderCursor(); break;
01938       default: return ES_NOT_HANDLED;
01939     }
01940     if (cbf != CBF_NONE) this->last_started_action = cbf;
01941     return ES_HANDLED;
01942   }
01943 
01944   virtual void OnPlaceObject(Point pt, TileIndex tile)
01945   {
01946     switch (this->last_started_action) {
01947       case CBF_PLACE_SIGN:
01948         PlaceProc_Sign(tile);
01949         break;
01950 
01951       case CBF_PLACE_LANDINFO:
01952         ShowLandInfo(tile);
01953         break;
01954 
01955       default: NOT_REACHED();
01956     }
01957   }
01958 
01959   virtual void OnTimeout()
01960   {
01961     this->SetWidgetsLoweredState(false, WID_TE_DATE_BACKWARD, WID_TE_DATE_FORWARD, WIDGET_LIST_END);
01962     this->SetWidgetDirty(WID_TE_DATE_BACKWARD);
01963     this->SetWidgetDirty(WID_TE_DATE_FORWARD);
01964   }
01965 
01966   virtual void OnTick()
01967   {
01968     if (this->IsWidgetLowered(WID_TE_PAUSE) != !!_pause_mode) {
01969       this->ToggleWidgetLoweredState(WID_TE_PAUSE);
01970       this->SetDirty();
01971     }
01972 
01973     if (this->IsWidgetLowered(WID_TE_FAST_FORWARD) != !!_fast_forward) {
01974       this->ToggleWidgetLoweredState(WID_TE_FAST_FORWARD);
01975       this->SetDirty();
01976     }
01977   }
01978 
01984   virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
01985   {
01986     if (!gui_scope) return;
01987     if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TE_ZOOM_IN, WID_TE_ZOOM_OUT);
01988   }
01989 
01990   virtual void OnQueryTextFinished(char *str)
01991   {
01992     /* Was 'cancel' pressed? */
01993     if (str == NULL) return;
01994 
01995     int32 value;
01996     if (!StrEmpty(str)) {
01997       value = atoi(str);
01998     } else {
01999       /* An empty string means revert to the default */
02000       value = DEF_START_YEAR;
02001     }
02002     _settings_game.game_creation.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
02003     SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
02004 
02005     this->SetDirty();
02006   }
02007 
02008   static Hotkey<ScenarioEditorToolbarWindow> scenedit_maintoolbar_hotkeys[];
02009 };
02010 
02011 Hotkey<ScenarioEditorToolbarWindow> ScenarioEditorToolbarWindow::scenedit_maintoolbar_hotkeys[] = {
02012   Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_pause_keys, "pause", MTEHK_PAUSE),
02013   Hotkey<ScenarioEditorToolbarWindow>((uint16)0, "fastforward", MTEHK_FASTFORWARD),
02014   Hotkey<ScenarioEditorToolbarWindow>(WKC_F2, "settings", MTEHK_SETTINGS),
02015   Hotkey<ScenarioEditorToolbarWindow>(WKC_F3, "saveload", MTEHK_SAVEGAME),
02016   Hotkey<ScenarioEditorToolbarWindow>(WKC_F4, "gen_land", MTEHK_GENLAND),
02017   Hotkey<ScenarioEditorToolbarWindow>(WKC_F5, "gen_town", MTEHK_GENTOWN),
02018   Hotkey<ScenarioEditorToolbarWindow>(WKC_F6, "gen_industry", MTEHK_GENINDUSTRY),
02019   Hotkey<ScenarioEditorToolbarWindow>(WKC_F7, "build_road", MTEHK_BUILD_ROAD),
02020   Hotkey<ScenarioEditorToolbarWindow>(WKC_F8, "build_docks", MTEHK_BUILD_DOCKS),
02021   Hotkey<ScenarioEditorToolbarWindow>(WKC_F9, "build_trees", MTEHK_BUILD_TREES),
02022   Hotkey<ScenarioEditorToolbarWindow>(WKC_F10, "build_sign", MTEHK_SIGN),
02023   Hotkey<ScenarioEditorToolbarWindow>(WKC_F11, "music", MTEHK_MUSIC),
02024   Hotkey<ScenarioEditorToolbarWindow>(WKC_F12, "land_info", MTEHK_LANDINFO),
02025   Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL  | 'S', "small_screenshot", MTEHK_SMALL_SCREENSHOT),
02026   Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL  | 'P', "zoomedin_screenshot", MTEHK_ZOOMEDIN_SCREENSHOT),
02027   Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL  | 'D', "defaultzoom_screenshot", MTEHK_DEFAULTZOOM_SCREENSHOT),
02028   Hotkey<ScenarioEditorToolbarWindow>((uint16)0, "giant_screenshot", MTEHK_GIANT_SCREENSHOT),
02029   Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_zoomin_keys, "zoomin", MTEHK_ZOOM_IN),
02030   Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_zoomout_keys, "zoomout", MTEHK_ZOOM_OUT),
02031   Hotkey<ScenarioEditorToolbarWindow>('L', "terraform", MTEHK_TERRAFORM),
02032   Hotkey<ScenarioEditorToolbarWindow>('M', "smallmap", MTEHK_SMALLMAP),
02033   Hotkey<ScenarioEditorToolbarWindow>('V', "extra_viewport", MTEHK_EXTRA_VIEWPORT),
02034   HOTKEY_LIST_END(ScenarioEditorToolbarWindow)
02035 };
02036 Hotkey<ScenarioEditorToolbarWindow> *_scenedit_maintoolbar_hotkeys = ScenarioEditorToolbarWindow::scenedit_maintoolbar_hotkeys;
02037 
02038 static const NWidgetPart _nested_toolb_scen_inner_widgets[] = {
02039   NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_PAUSE), SetDataTip(SPR_IMG_PAUSE, STR_TOOLBAR_TOOLTIP_PAUSE_GAME),
02040   NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_FAST_FORWARD), SetDataTip(SPR_IMG_FASTFORWARD, STR_TOOLBAR_TOOLTIP_FORWARD),
02041   NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SETTINGS), SetDataTip(SPR_IMG_SETTINGS, STR_TOOLBAR_TOOLTIP_OPTIONS),
02042   NWidget(WWT_IMGBTN_2, COLOUR_GREY, WID_TE_SAVE), SetDataTip(SPR_IMG_SAVE, STR_SCENEDIT_TOOLBAR_TOOLTIP_SAVE_SCENARIO_LOAD_SCENARIO),
02043   NWidget(NWID_SPACER),
02044   NWidget(WWT_PANEL, COLOUR_GREY, WID_TE_SPACER), EndContainer(),
02045   NWidget(NWID_SPACER),
02046   NWidget(WWT_PANEL, COLOUR_GREY, WID_TE_DATE_PANEL),
02047     NWidget(NWID_HORIZONTAL), SetPIP(3, 2, 3),
02048       NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_DATE_BACKWARD), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD),
02049       NWidget(WWT_EMPTY, COLOUR_GREY, WID_TE_DATE), SetDataTip(STR_NULL, STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE),
02050       NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_DATE_FORWARD), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD),
02051     EndContainer(),
02052   EndContainer(),
02053   NWidget(NWID_SPACER),
02054   NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SMALL_MAP), SetDataTip(SPR_IMG_SMALLMAP, STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY),
02055   NWidget(NWID_SPACER),
02056   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ZOOM_IN), SetDataTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN),
02057   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ZOOM_OUT), SetDataTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT),
02058   NWidget(NWID_SPACER),
02059   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_LAND_GENERATE), SetDataTip(SPR_IMG_LANDSCAPING, STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION),
02060   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_TOWN_GENERATE), SetDataTip(SPR_IMG_TOWN, STR_SCENEDIT_TOOLBAR_TOWN_GENERATION),
02061   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_INDUSTRY), SetDataTip(SPR_IMG_INDUSTRY, STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION),
02062   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ROADS), SetDataTip(SPR_IMG_BUILDROAD, STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION),
02063   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_WATER), SetDataTip(SPR_IMG_BUILDWATER, STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS),
02064   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_TREES), SetDataTip(SPR_IMG_PLANTTREES, STR_SCENEDIT_TOOLBAR_PLANT_TREES),
02065   NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_SIGNS), SetDataTip(SPR_IMG_SIGN, STR_SCENEDIT_TOOLBAR_PLACE_SIGN),
02066   NWidget(NWID_SPACER),
02067   NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_MUSIC_SOUND), SetDataTip(SPR_IMG_MUSIC, STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW),
02068   NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_HELP), SetDataTip(SPR_IMG_QUERY, STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION),
02069   NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SWITCH_BAR), SetDataTip(SPR_IMG_SWITCH_TOOLBAR, STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR),
02070 };
02071 
02072 static NWidgetBase *MakeScenarioToolbar(int *biggest_index)
02073 {
02074   return MakeNWidgets(_nested_toolb_scen_inner_widgets, lengthof(_nested_toolb_scen_inner_widgets), biggest_index, new NWidgetScenarioToolbarContainer());
02075 }
02076 
02077 static const NWidgetPart _nested_toolb_scen_widgets[] = {
02078   NWidgetFunction(MakeScenarioToolbar),
02079 };
02080 
02081 static WindowDesc _toolb_scen_desc(
02082   WDP_MANUAL, 640, 22,
02083   WC_MAIN_TOOLBAR, WC_NONE,
02084   WDF_NO_FOCUS,
02085   _nested_toolb_scen_widgets, lengthof(_nested_toolb_scen_widgets)
02086 );
02087 
02089 void AllocateToolbar()
02090 {
02091   /* Clean old GUI values; railtype is (re)set by rail_gui.cpp */
02092   _last_built_roadtype = ROADTYPE_ROAD;
02093 
02094   if (_game_mode == GM_EDITOR) {
02095     _preferred_toolbar_size = &_toolb_scen_desc.default_width;
02096     new ScenarioEditorToolbarWindow(&_toolb_scen_desc);
02097   } else {
02098     _preferred_toolbar_size = &_toolb_normal_desc.default_width;
02099     new MainToolbarWindow(&_toolb_normal_desc);
02100   }
02101 }