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