src/main_gui.cpp
changeset 10235 684949ed0f03
parent 10083 9fb63cf5cc90
child 10236 62a0a74e7332
equal deleted inserted replaced
10234:a7ffe39edea9 10235:684949ed0f03
     2 
     2 
     3 /** @file main_gui.cpp */
     3 /** @file main_gui.cpp */
     4 
     4 
     5 #include "stdafx.h"
     5 #include "stdafx.h"
     6 #include "openttd.h"
     6 #include "openttd.h"
     7 #include "heightmap.h"
       
     8 #include "currency.h"
     7 #include "currency.h"
     9 #include "spritecache.h"
     8 #include "spritecache.h"
    10 #include "gui.h"
     9 #include "gui.h"
    11 #include "window_gui.h"
    10 #include "window_gui.h"
    12 #include "window_func.h"
    11 #include "window_func.h"
    13 #include "textbuf_gui.h"
    12 #include "textbuf_gui.h"
    14 #include "viewport_func.h"
    13 #include "viewport_func.h"
    15 #include "command_func.h"
    14 #include "command_func.h"
    16 #include "news_func.h"
    15 #include "news_func.h"
    17 #include "town.h"
       
    18 #include "console.h"
    16 #include "console.h"
    19 #include "signs_func.h"
       
    20 #include "waypoint.h"
    17 #include "waypoint.h"
    21 #include "variables.h"
       
    22 #include "train.h"
       
    23 #include "roadveh.h"
       
    24 #include "bridge_map.h"
       
    25 #include "screenshot.h"
       
    26 #include "genworld.h"
    18 #include "genworld.h"
    27 #include "vehicle_gui.h"
       
    28 #include "transparency_gui.h"
    19 #include "transparency_gui.h"
    29 #include "newgrf_config.h"
       
    30 #include "rail_gui.h"
       
    31 #include "road_gui.h"
       
    32 #include "date_func.h"
    20 #include "date_func.h"
    33 #include "functions.h"
    21 #include "functions.h"
    34 #include "vehicle_func.h"
       
    35 #include "sound_func.h"
    22 #include "sound_func.h"
    36 #include "fios.h"
       
    37 #include "terraform_gui.h"
       
    38 #include "industry.h"
       
    39 #include "transparency.h"
    23 #include "transparency.h"
    40 #include "strings_func.h"
    24 #include "strings_func.h"
    41 #include "zoom_func.h"
    25 #include "zoom_func.h"
    42 #include "string_func.h"
    26 #include "string_func.h"
    43 #include "player_base.h"
    27 #include "player_base.h"
    44 #include "player_func.h"
    28 #include "player_func.h"
    45 #include "player_gui.h"
    29 #include "player_gui.h"
    46 #include "settings_type.h"
    30 #include "settings_type.h"
    47 #include "toolbar_gui.h"
    31 #include "toolbar_gui.h"
       
    32 #include "variables.h"
    48 
    33 
    49 #include "network/network.h"
    34 #include "network/network.h"
    50 #include "network/network_data.h"
    35 #include "network/network_data.h"
    51 #include "network/network_client.h"
    36 #include "network/network_client.h"
    52 #include "network/network_server.h"
    37 #include "network/network_server.h"
    56 #include "table/strings.h"
    41 #include "table/strings.h"
    57 
    42 
    58 static int _rename_id = 1;
    43 static int _rename_id = 1;
    59 static int _rename_what = -1;
    44 static int _rename_what = -1;
    60 
    45 
    61 RailType _last_built_railtype;
       
    62 RoadType _last_built_roadtype;
       
    63 bool _draw_bounding_boxes = false;
    46 bool _draw_bounding_boxes = false;
    64 
    47 
    65 
    48 
    66 void CcGiveMoney(bool success, TileIndex tile, uint32 p1, uint32 p2)
    49 void CcGiveMoney(bool success, TileIndex tile, uint32 p1, uint32 p2)
    67 {
    50 {
   140 void CcPlaySound10(bool success, TileIndex tile, uint32 p1, uint32 p2)
   123 void CcPlaySound10(bool success, TileIndex tile, uint32 p1, uint32 p2)
   141 {
   124 {
   142 	if (success) SndPlayTileFx(SND_12_EXPLOSION, tile);
   125 	if (success) SndPlayTileFx(SND_12_EXPLOSION, tile);
   143 }
   126 }
   144 
   127 
   145 
       
   146 static void MenuClickSettings(int index)
       
   147 {
       
   148 	switch (index) {
       
   149 		case 0: ShowGameOptions();      return;
       
   150 		case 1: ShowGameDifficulty();   return;
       
   151 		case 2: ShowPatchesSelection(); return;
       
   152 		case 3: ShowNewGRFSettings(!_networking, true, true, &_grfconfig);   return;
       
   153 		case 4: ShowTransparencyToolbar(); break;
       
   154 
       
   155 		case  6: ToggleBit(_display_opt, DO_SHOW_TOWN_NAMES);    break;
       
   156 		case  7: ToggleBit(_display_opt, DO_SHOW_STATION_NAMES); break;
       
   157 		case  8: ToggleBit(_display_opt, DO_SHOW_SIGNS);         break;
       
   158 		case  9: ToggleBit(_display_opt, DO_WAYPOINTS);          break;
       
   159 		case 10: ToggleBit(_display_opt, DO_FULL_ANIMATION);     break;
       
   160 		case 11: ToggleBit(_display_opt, DO_FULL_DETAIL);        break;
       
   161 		case 12: ToggleTransparency(TO_HOUSES);                  break;
       
   162 		case 13: ToggleTransparency(TO_SIGNS);                   break;
       
   163 	}
       
   164 	MarkWholeScreenDirty();
       
   165 }
       
   166 
       
   167 void MenuClickSaveLoad(int index)
       
   168 {
       
   169 	if (_game_mode == GM_EDITOR) {
       
   170 		switch (index) {
       
   171 			case 0: ShowSaveLoadDialog(SLD_SAVE_SCENARIO);  break;
       
   172 			case 1: ShowSaveLoadDialog(SLD_LOAD_SCENARIO);  break;
       
   173 			case 2: ShowSaveLoadDialog(SLD_LOAD_HEIGHTMAP); break;
       
   174 			case 3: AskExitToGameMenu();                    break;
       
   175 			case 5: HandleExitGameRequest();                break;
       
   176 		}
       
   177 	} else {
       
   178 		switch (index) {
       
   179 			case 0: ShowSaveLoadDialog(SLD_SAVE_GAME); break;
       
   180 			case 1: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
       
   181 			case 2: AskExitToGameMenu();               break;
       
   182 			case 3: HandleExitGameRequest();           break;
       
   183 		}
       
   184 	}
       
   185 }
       
   186 
       
   187 static void MenuClickMap(int index)
       
   188 {
       
   189 	switch (index) {
       
   190 		case 0: ShowSmallMap();            break;
       
   191 		case 1: ShowExtraViewPortWindow(); break;
       
   192 		case 2: ShowSignList();            break;
       
   193 	}
       
   194 }
       
   195 
       
   196 static void MenuClickTown(int index)
       
   197 {
       
   198 	ShowTownDirectory();
       
   199 }
       
   200 
       
   201 static void MenuClickScenMap(int index)
       
   202 {
       
   203 	switch (index) {
       
   204 		case 0: ShowSmallMap();            break;
       
   205 		case 1: ShowExtraViewPortWindow(); break;
       
   206 		case 2: ShowSignList();            break;
       
   207 		case 3: ShowTownDirectory();       break;
       
   208 	}
       
   209 }
       
   210 
       
   211 static void MenuClickSubsidies(int index)
       
   212 {
       
   213 	ShowSubsidiesList();
       
   214 }
       
   215 
       
   216 static void MenuClickStations(int index)
       
   217 {
       
   218 	ShowPlayerStations((PlayerID)index);
       
   219 }
       
   220 
       
   221 static void MenuClickFinances(int index)
       
   222 {
       
   223 	ShowPlayerFinances((PlayerID)index);
       
   224 }
       
   225 
       
   226 static void MenuClickCompany(int index)
       
   227 {
       
   228 	if (_networking && index == 0) {
       
   229 		ShowClientList();
       
   230 	} else {
       
   231 		if (_networking) index--;
       
   232 		ShowPlayerCompany((PlayerID)index);
       
   233 	}
       
   234 }
       
   235 
       
   236 static void MenuClickGraphs(int index)
       
   237 {
       
   238 	switch (index) {
       
   239 		case 0: ShowOperatingProfitGraph();    break;
       
   240 		case 1: ShowIncomeGraph();             break;
       
   241 		case 2: ShowDeliveredCargoGraph();     break;
       
   242 		case 3: ShowPerformanceHistoryGraph(); break;
       
   243 		case 4: ShowCompanyValueGraph();       break;
       
   244 		case 5: ShowCargoPaymentRates();       break;
       
   245 	}
       
   246 }
       
   247 
       
   248 static void MenuClickLeague(int index)
       
   249 {
       
   250 	switch (index) {
       
   251 		case 0: ShowCompanyLeagueTable();      break;
       
   252 		case 1: ShowPerformanceRatingDetail(); break;
       
   253 	}
       
   254 }
       
   255 
       
   256 static void MenuClickIndustry(int index)
       
   257 {
       
   258 	switch (index) {
       
   259 		case 0: ShowIndustryDirectory();   break;
       
   260 		case 1: ShowBuildIndustryWindow(); break;
       
   261 	}
       
   262 }
       
   263 
       
   264 static void MenuClickShowTrains(int index)
       
   265 {
       
   266 	ShowVehicleListWindow((PlayerID)index, VEH_TRAIN);
       
   267 }
       
   268 
       
   269 static void MenuClickShowRoad(int index)
       
   270 {
       
   271 	ShowVehicleListWindow((PlayerID)index, VEH_ROAD);
       
   272 }
       
   273 
       
   274 static void MenuClickShowShips(int index)
       
   275 {
       
   276 	ShowVehicleListWindow((PlayerID)index, VEH_SHIP);
       
   277 }
       
   278 
       
   279 static void MenuClickShowAir(int index)
       
   280 {
       
   281 	ShowVehicleListWindow((PlayerID)index, VEH_AIRCRAFT);
       
   282 }
       
   283 
       
   284 static void MenuClickBuildRail(int index)
       
   285 {
       
   286 	_last_built_railtype = (RailType)index;
       
   287 	ShowBuildRailToolbar(_last_built_railtype, -1);
       
   288 }
       
   289 
       
   290 static void MenuClickBuildRoad(int index)
       
   291 {
       
   292 	_last_built_roadtype = (RoadType)index;
       
   293 	ShowBuildRoadToolbar(_last_built_roadtype);
       
   294 }
       
   295 
       
   296 static void MenuClickBuildWater(int index)
       
   297 {
       
   298 	ShowBuildDocksToolbar();
       
   299 }
       
   300 
       
   301 static void MenuClickBuildAir(int index)
       
   302 {
       
   303 	ShowBuildAirToolbar();
       
   304 }
       
   305 
       
   306 #ifdef ENABLE_NETWORK
   128 #ifdef ENABLE_NETWORK
   307 void ShowNetworkGiveMoneyWindow(PlayerID player)
   129 void ShowNetworkGiveMoneyWindow(PlayerID player)
   308 {
   130 {
   309 	_rename_id = player;
   131 	_rename_id = player;
   310 	_rename_what = 3;
   132 	_rename_what = 3;
   327 	_rename_what = 1;
   149 	_rename_what = 1;
   328 	SetDParam(0, id);
   150 	SetDParam(0, id);
   329 	ShowQueryString(STR_WAYPOINT_RAW, STR_EDIT_WAYPOINT_NAME, 30, 180, NULL, CS_ALPHANUMERAL);
   151 	ShowQueryString(STR_WAYPOINT_RAW, STR_EDIT_WAYPOINT_NAME, 30, 180, NULL, CS_ALPHANUMERAL);
   330 }
   152 }
   331 
   153 
   332 void SelectSignTool()
       
   333 {
       
   334 	if (_cursor.sprite == SPR_CURSOR_SIGN) {
       
   335 		ResetObjectToPlace();
       
   336 	} else {
       
   337 		SetObjectToPlace(SPR_CURSOR_SIGN, PAL_NONE, VHM_RECT, WC_MAIN_TOOLBAR, 0);
       
   338 		_place_proc = PlaceProc_Sign;
       
   339 	}
       
   340 }
       
   341 
       
   342 static void MenuClickForest(int index)
       
   343 {
       
   344 	switch (index) {
       
   345 		case 0: ShowTerraformToolbar();  break;
       
   346 		case 1: ShowBuildTreesToolbar(); break;
       
   347 		case 2: SelectSignTool();        break;
       
   348 	}
       
   349 }
       
   350 
       
   351 static void MenuClickMusicWindow(int index)
       
   352 {
       
   353 	ShowMusicWindow();
       
   354 }
       
   355 
       
   356 static void MenuClickNewspaper(int index)
       
   357 {
       
   358 	switch (index) {
       
   359 		case 0: ShowLastNewsMessage(); break;
       
   360 		case 1: ShowMessageOptions();  break;
       
   361 		case 2: ShowMessageHistory();  break;
       
   362 	}
       
   363 }
       
   364 
       
   365 void MenuClickSmallScreenshot()
       
   366 {
       
   367 	SetScreenshotType(SC_VIEWPORT);
       
   368 }
       
   369 
       
   370 void MenuClickWorldScreenshot()
       
   371 {
       
   372 	SetScreenshotType(SC_WORLD);
       
   373 }
       
   374 
       
   375 static void MenuClickHelp(int index)
       
   376 {
       
   377 	switch (index) {
       
   378 		case 0: PlaceLandBlockInfo();       break;
       
   379 		case 2: IConsoleSwitch();           break;
       
   380 		case 3: MenuClickSmallScreenshot(); break;
       
   381 		case 4: MenuClickWorldScreenshot(); break;
       
   382 		case 5: ShowAboutWindow();          break;
       
   383 	}
       
   384 }
       
   385 
       
   386 
       
   387 typedef void MenuClickedProc(int index);
       
   388 
       
   389 static MenuClickedProc * const _menu_clicked_procs[] = {
       
   390 	NULL,                 /* 0 */
       
   391 	NULL,                 /* 1 */
       
   392 	MenuClickSettings,    /* 2 */
       
   393 	MenuClickSaveLoad,    /* 3 */
       
   394 	MenuClickMap,         /* 4 */
       
   395 	MenuClickTown,        /* 5 */
       
   396 	MenuClickSubsidies,   /* 6 */
       
   397 	MenuClickStations,    /* 7 */
       
   398 	MenuClickFinances,    /* 8 */
       
   399 	MenuClickCompany,     /* 9 */
       
   400 	MenuClickGraphs,      /* 10 */
       
   401 	MenuClickLeague,      /* 11 */
       
   402 	MenuClickIndustry,    /* 12 */
       
   403 	MenuClickShowTrains,  /* 13 */
       
   404 	MenuClickShowRoad,    /* 14 */
       
   405 	MenuClickShowShips,   /* 15 */
       
   406 	MenuClickShowAir,     /* 16 */
       
   407 	MenuClickScenMap,     /* 17 */
       
   408 	NULL,                 /* 18 */
       
   409 	MenuClickBuildRail,   /* 19 */
       
   410 	MenuClickBuildRoad,   /* 20 */
       
   411 	MenuClickBuildWater,  /* 21 */
       
   412 	MenuClickBuildAir,    /* 22 */
       
   413 	MenuClickForest,      /* 23 */
       
   414 	MenuClickMusicWindow, /* 24 */
       
   415 	MenuClickNewspaper,   /* 25 */
       
   416 	MenuClickHelp,        /* 26 */
       
   417 };
       
   418 
       
   419 static void MenuWndProc(Window *w, WindowEvent *e)
       
   420 {
       
   421 	switch (e->event) {
       
   422 		case WE_CREATE: w->widget[0].right = w->width - 1; break;
       
   423 
       
   424 	case WE_PAINT: {
       
   425 		int x, y;
       
   426 
       
   427 		byte count = WP(w, menu_d).item_count;
       
   428 		byte sel = WP(w, menu_d).sel_index;
       
   429 		uint16 chk = WP(w, menu_d).checked_items;
       
   430 		StringID string = WP(w, menu_d).string_id;
       
   431 		byte dis = WP(w, menu_d).disabled_items;
       
   432 
       
   433 		DrawWindowWidgets(w);
       
   434 
       
   435 		x = 1;
       
   436 		y = 1;
       
   437 
       
   438 		for (; count != 0; count--, string++, sel--) {
       
   439 			TextColour color = HasBit(dis, 0) ? TC_GREY : (sel == 0) ? TC_WHITE : TC_BLACK;
       
   440 			if (sel == 0) GfxFillRect(x, y, x + w->width - 3, y + 9, 0);
       
   441 
       
   442 			if (HasBit(chk, 0)) DrawString(x + 2, y, STR_CHECKMARK, color);
       
   443 			DrawString(x + 2, y, string, color);
       
   444 
       
   445 			y += 10;
       
   446 			chk >>= 1;
       
   447 			dis >>= 1;
       
   448 		}
       
   449 	} break;
       
   450 
       
   451 	case WE_DESTROY: {
       
   452 			Window *v = FindWindowById(WC_MAIN_TOOLBAR, 0);
       
   453 			v->RaiseWidget(WP(w, menu_d).main_button);
       
   454 			SetWindowDirty(v);
       
   455 			return;
       
   456 		}
       
   457 
       
   458 	case WE_POPUPMENU_SELECT: {
       
   459 		int index = GetMenuItemIndex(w, e->we.popupmenu.pt.x, e->we.popupmenu.pt.y);
       
   460 		int action_id;
       
   461 
       
   462 
       
   463 		if (index < 0) {
       
   464 			Window *w2 = FindWindowById(WC_MAIN_TOOLBAR,0);
       
   465 			if (GetWidgetFromPos(w2, e->we.popupmenu.pt.x - w2->left, e->we.popupmenu.pt.y - w2->top) == WP(w, menu_d).main_button)
       
   466 				index = WP(w, menu_d).sel_index;
       
   467 		}
       
   468 
       
   469 		action_id = WP(w, menu_d).action_id;
       
   470 		DeleteWindow(w);
       
   471 
       
   472 		if (index >= 0) {
       
   473 			assert((uint)index <= lengthof(_menu_clicked_procs));
       
   474 			_menu_clicked_procs[action_id](index);
       
   475 		}
       
   476 
       
   477 		break;
       
   478 		}
       
   479 
       
   480 	case WE_POPUPMENU_OVER: {
       
   481 		int index = GetMenuItemIndex(w, e->we.popupmenu.pt.x, e->we.popupmenu.pt.y);
       
   482 
       
   483 		if (index == -1 || index == WP(w, menu_d).sel_index) return;
       
   484 
       
   485 		WP(w, menu_d).sel_index = index;
       
   486 		SetWindowDirty(w);
       
   487 		return;
       
   488 		}
       
   489 	}
       
   490 }
       
   491 
       
   492 /* Dynamic widget length determined by toolbar-string length.
       
   493  * See PopupMainToolbMenu en MenuWndProc */
       
   494 static const Widget _menu_widgets[] = {
       
   495 {    WWT_PANEL, RESIZE_NONE, 14, 0,  0, 0, 0, 0x0, STR_NULL},
       
   496 { WIDGETS_END},
       
   497 };
       
   498 
       
   499 
       
   500 static const Widget _player_menu_widgets[] = {
       
   501 {    WWT_PANEL, RESIZE_NONE, 14, 0, 240, 0, 81, 0x0, STR_NULL},
       
   502 { WIDGETS_END},
       
   503 };
       
   504 
       
   505 
       
   506 static int GetPlayerIndexFromMenu(int index)
       
   507 {
       
   508 	if (index >= 0) {
       
   509 		const Player *p;
       
   510 
       
   511 		FOR_ALL_PLAYERS(p) {
       
   512 			if (p->is_active && --index < 0) return p->index;
       
   513 		}
       
   514 	}
       
   515 	return -1;
       
   516 }
       
   517 
       
   518 static void UpdatePlayerMenuHeight(Window *w)
       
   519 {
       
   520 	byte num = ActivePlayerCount();
       
   521 
       
   522 	/* Increase one to fit in PlayerList in the menu when in network */
       
   523 	if (_networking && WP(w, menu_d).main_button == 9) num++;
       
   524 
       
   525 	if (WP(w, menu_d).item_count != num) {
       
   526 		WP(w, menu_d).item_count = num;
       
   527 		SetWindowDirty(w);
       
   528 		num = num * 10 + 2;
       
   529 		w->height = num;
       
   530 		w->widget[0].bottom = w->widget[0].top + num - 1;
       
   531 		w->top = GetToolbarDropdownPos(0, w->width, w->height).y;
       
   532 		SetWindowDirty(w);
       
   533 	}
       
   534 }
       
   535 
       
   536 static void PlayerMenuWndProc(Window *w, WindowEvent *e)
       
   537 {
       
   538 	switch (e->event) {
       
   539 	case WE_PAINT: {
       
   540 		int x,y;
       
   541 		byte sel;
       
   542 		TextColour color;
       
   543 		Player *p;
       
   544 		uint16 chk;
       
   545 
       
   546 		UpdatePlayerMenuHeight(w);
       
   547 		DrawWindowWidgets(w);
       
   548 
       
   549 		x = 1;
       
   550 		y = 1;
       
   551 		sel = WP(w, menu_d).sel_index;
       
   552 		chk = WP(w, menu_d).checked_items; // let this mean gray items.
       
   553 
       
   554 		/* 9 = playerlist */
       
   555 		if (_networking && WP(w, menu_d).main_button == 9) {
       
   556 			if (sel == 0) {
       
   557 				GfxFillRect(x, y, x + 238, y + 9, 0);
       
   558 			}
       
   559 			DrawString(x + 19, y, STR_NETWORK_CLIENT_LIST, TC_FROMSTRING);
       
   560 			y += 10;
       
   561 			sel--;
       
   562 		}
       
   563 
       
   564 		FOR_ALL_PLAYERS(p) {
       
   565 			if (p->is_active) {
       
   566 				if (p->index == sel) {
       
   567 					GfxFillRect(x, y, x + 238, y + 9, 0);
       
   568 				}
       
   569 
       
   570 				DrawPlayerIcon(p->index, x + 2, y + 1);
       
   571 
       
   572 				SetDParam(0, p->index);
       
   573 				SetDParam(1, p->index);
       
   574 
       
   575 				color = (p->index == sel) ? TC_WHITE : TC_BLACK;
       
   576 				if (chk&1) color = TC_GREY;
       
   577 				DrawString(x + 19, y, STR_7021, color);
       
   578 
       
   579 				y += 10;
       
   580 			}
       
   581 			chk >>= 1;
       
   582 		}
       
   583 
       
   584 		break;
       
   585 		}
       
   586 
       
   587 	case WE_DESTROY: {
       
   588 		Window *v = FindWindowById(WC_MAIN_TOOLBAR, 0);
       
   589 		v->RaiseWidget(WP(w, menu_d).main_button);
       
   590 		SetWindowDirty(v);
       
   591 		return;
       
   592 		}
       
   593 
       
   594 	case WE_POPUPMENU_SELECT: {
       
   595 		int index = GetMenuItemIndex(w, e->we.popupmenu.pt.x, e->we.popupmenu.pt.y);
       
   596 		int action_id = WP(w, menu_d).action_id;
       
   597 
       
   598 		/* We have a new entry at the top of the list of menu 9 when networking
       
   599 		 *  so keep that in count */
       
   600 		if (_networking && WP(w, menu_d).main_button == 9) {
       
   601 			if (index > 0) index = GetPlayerIndexFromMenu(index - 1) + 1;
       
   602 		} else {
       
   603 			index = GetPlayerIndexFromMenu(index);
       
   604 		}
       
   605 
       
   606 		if (index < 0) {
       
   607 			Window *w2 = FindWindowById(WC_MAIN_TOOLBAR,0);
       
   608 			if (GetWidgetFromPos(w2, e->we.popupmenu.pt.x - w2->left, e->we.popupmenu.pt.y - w2->top) == WP(w, menu_d).main_button)
       
   609 				index = WP(w, menu_d).sel_index;
       
   610 		}
       
   611 
       
   612 		DeleteWindow(w);
       
   613 
       
   614 		if (index >= 0) {
       
   615 			assert(index >= 0 && index < 30);
       
   616 			_menu_clicked_procs[action_id](index);
       
   617 		}
       
   618 		break;
       
   619 		}
       
   620 	case WE_POPUPMENU_OVER: {
       
   621 		int index;
       
   622 		UpdatePlayerMenuHeight(w);
       
   623 		index = GetMenuItemIndex(w, e->we.popupmenu.pt.x, e->we.popupmenu.pt.y);
       
   624 
       
   625 		/* We have a new entry at the top of the list of menu 9 when networking
       
   626 		 * so keep that in count */
       
   627 		if (_networking && WP(w, menu_d).main_button == 9) {
       
   628 			if (index > 0) index = GetPlayerIndexFromMenu(index - 1) + 1;
       
   629 		} else {
       
   630 			index = GetPlayerIndexFromMenu(index);
       
   631 		}
       
   632 
       
   633 		if (index == -1 || index == WP(w, menu_d).sel_index) return;
       
   634 
       
   635 		WP(w, menu_d).sel_index = index;
       
   636 		SetWindowDirty(w);
       
   637 		return;
       
   638 		}
       
   639 	}
       
   640 }
       
   641 
       
   642 /** Get the maximum length of a given string in a string-list. This is an
       
   643  * implicit string-list where the ID's are consecutive
       
   644  * @param base_string StringID of the first string in the list
       
   645  * @param count amount of StringID's in the list
       
   646  * @return the length of the longest string */
       
   647 static int GetStringListMaxWidth(StringID base_string, byte count)
       
   648 {
       
   649 	char buffer[512];
       
   650 	int width, max_width;
       
   651 	byte i;
       
   652 
       
   653 	max_width = 0;
       
   654 	for (i = 0; i != count; i++) {
       
   655 		GetString(buffer, base_string + i, lastof(buffer));
       
   656 		width = GetStringBoundingBox(buffer).width;
       
   657 		if (width > max_width) max_width = width;
       
   658 	}
       
   659 
       
   660 	return max_width;
       
   661 }
       
   662 
       
   663 /** Show a general dropdown menu. The positioning of the dropdown menu
       
   664  * defaults to the left side of the parent_button, eg the button that caused
       
   665  * this window to appear. The only exceptions are when the right side of this
       
   666  * dropdown would fall outside the main toolbar window, in that case it is
       
   667  * aligned with the toolbar's right side.
       
   668  * Since the disable-mask is only 8 bits right now, these dropdowns are
       
   669  * restricted to 8 items max if any bits of disabled_mask are active.
       
   670  * @param w Pointer to a window this dropdown menu belongs to. Has no effect
       
   671  * whatsoever, only graphically for positioning.
       
   672  * @param parent_button The widget identifier of the button that was clicked for
       
   673  * this dropdown. The created dropdown then knows what button to raise (button) on
       
   674  * action and whose function to execute (action).
       
   675  * It is possible to appoint another button for an action event by setting the
       
   676  * upper 8 bits of this parameter. If non is set, action is presumed to be the same
       
   677  * as button. So<br>
       
   678  * button bits 0 -  7 - widget clicked to get dropdown
       
   679  * action bits 8 - 15 - function of widget to execute on select (defaults to bits 0 - 7)
       
   680  * @param base_string The first StringID shown in the dropdown list. All others are
       
   681  * consecutive indeces from the language file. XXX - fix? Use ingame-string tables?
       
   682  * @param item_count Number of strings in the list, see previous parameter
       
   683  * @param disabled_mask Bitmask of disabled strings in the list
       
   684  * @return Return a pointer to the newly created dropdown window */
       
   685  Window *PopupMainToolbMenu(Window *w, uint16 parent_button, StringID base_string, byte item_count, byte disabled_mask)
       
   686 {
       
   687 	assert(disabled_mask == 0 || item_count <= 8);
       
   688 	w->LowerWidget(parent_button);
       
   689 	w->InvalidateWidget(parent_button);
       
   690 
       
   691 	DeleteWindowById(WC_TOOLBAR_MENU, 0);
       
   692 
       
   693 	// Extend the dropdown toolbar to the longest string in the list
       
   694 	int width = max(GetStringListMaxWidth(base_string, item_count) + 6, 140);
       
   695 	int height = item_count * 10 + 2;
       
   696 
       
   697 	Point pos = GetToolbarDropdownPos(parent_button, width, height);
       
   698 
       
   699 	w = AllocateWindow(pos.x, pos.y, width, height, MenuWndProc, WC_TOOLBAR_MENU, _menu_widgets);
       
   700 	w->widget[0].bottom = item_count * 10 + 1;
       
   701 	w->flags4 &= ~WF_WHITE_BORDER_MASK;
       
   702 
       
   703 	WP(w, menu_d).item_count = item_count;
       
   704 	WP(w, menu_d).sel_index = 0;
       
   705 	WP(w, menu_d).main_button = GB(parent_button, 0, 8);
       
   706 	WP(w, menu_d).action_id = (GB(parent_button, 8, 8) != 0) ? GB(parent_button, 8, 8) : parent_button;
       
   707 	WP(w, menu_d).string_id = base_string;
       
   708 	WP(w, menu_d).checked_items = 0;
       
   709 	WP(w, menu_d).disabled_items = disabled_mask;
       
   710 
       
   711 	_popup_menu_active = true;
       
   712 
       
   713 	SndPlayFx(SND_15_BEEP);
       
   714 	return w;
       
   715 }
       
   716 
       
   717 Window *PopupMainPlayerToolbMenu(Window *w, int main_button, int gray)
       
   718 {
       
   719 	w->LowerWidget(main_button);
       
   720 	w->InvalidateWidget(main_button);
       
   721 
       
   722 	DeleteWindowById(WC_TOOLBAR_MENU, 0);
       
   723 	Point pos = GetToolbarDropdownPos(main_button, 241, 82);
       
   724 	w = AllocateWindow(pos.x, pos.y, 241, 82, PlayerMenuWndProc, WC_TOOLBAR_MENU, _player_menu_widgets);
       
   725 	w->flags4 &= ~WF_WHITE_BORDER_MASK;
       
   726 	WP(w, menu_d).item_count = 0;
       
   727 	WP(w, menu_d).sel_index = (_local_player != PLAYER_SPECTATOR) ? _local_player : GetPlayerIndexFromMenu(0);
       
   728 	if (_networking && main_button == 9) {
       
   729 		if (_local_player != PLAYER_SPECTATOR) {
       
   730 			WP(w, menu_d).sel_index++;
       
   731 		} else {
       
   732 			/* Select client list by default for spectators */
       
   733 			WP(w, menu_d).sel_index = 0;
       
   734 		}
       
   735 	}
       
   736 	WP(w, menu_d).action_id = main_button;
       
   737 	WP(w, menu_d).main_button = main_button;
       
   738 	WP(w, menu_d).checked_items = gray;
       
   739 	WP(w, menu_d).disabled_items = 0;
       
   740 	_popup_menu_active = true;
       
   741 	SndPlayFx(SND_15_BEEP);
       
   742 	return w;
       
   743 }
       
   744 
   154 
   745 /* Zooms a viewport in a window in or out */
   155 /* Zooms a viewport in a window in or out */
   746 /* No button handling or what so ever */
   156 /* No button handling or what so ever */
   747 bool DoZoomInOutWindow(int how, Window *w)
   157 bool DoZoomInOutWindow(int how, Window *w)
   748 {
   158 {
  1194 void ShowVitalWindows()
   604 void ShowVitalWindows()
  1195 {
   605 {
  1196 	Window *w = AllocateToolbar();
   606 	Window *w = AllocateToolbar();
  1197 	DoZoomInOutWindow(ZOOM_NONE, w);
   607 	DoZoomInOutWindow(ZOOM_NONE, w);
  1198 
   608 
  1199 	CLRBITS(w->flags4, WF_WHITE_BORDER_MASK);
       
  1200 
       
  1201 	w->SetWidgetDisabledState(0, _networking && !_network_server); // if not server, disable pause button
       
  1202 	w->SetWidgetDisabledState(1, _networking); // if networking, disable fast-forward button
       
  1203 
       
  1204 	/* 'w' is for sure a WC_MAIN_TOOLBAR */
       
  1205 	PositionMainToolbar(w);
       
  1206 
       
  1207 	/* Status bad only for normal games */
   609 	/* Status bad only for normal games */
  1208 	if (_game_mode == GM_EDITOR) return;
   610 	if (_game_mode == GM_EDITOR) return;
  1209 
   611 
  1210 	_main_status_desc.top = _screen.height - 12;
   612 	_main_status_desc.top = _screen.height - 12;
  1211 	w = AllocateWindowDesc(&_main_status_desc);
   613 	w = AllocateWindowDesc(&_main_status_desc);
  1224 	_cur_resolution[1] = _screen.height;
   626 	_cur_resolution[1] = _screen.height;
  1225 	RelocateAllWindows(_screen.width, _screen.height);
   627 	RelocateAllWindows(_screen.width, _screen.height);
  1226 	ScreenSizeChanged();
   628 	ScreenSizeChanged();
  1227 	MarkWholeScreenDirty();
   629 	MarkWholeScreenDirty();
  1228 }
   630 }
  1229 
       
  1230 void InitializeMainGui()
       
  1231 {
       
  1232 	/* Clean old GUI values */
       
  1233 	_last_built_railtype = RAILTYPE_RAIL;
       
  1234 	_last_built_roadtype = ROADTYPE_ROAD;
       
  1235 }
       
  1236 
       
  1237 
       
  1238 
       
  1239 
       
  1240