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