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