src/network/network_gui.cpp
changeset 8456 bec1891e42b5
parent 8455 218ce4bc9b23
child 8457 6e4071463e64
equal deleted inserted replaced
8455:218ce4bc9b23 8456:bec1891e42b5
   207 	item->next = NULL;
   207 	item->next = NULL;
   208 
   208 
   209 	nqld->l.flags &= ~VL_RESORT;
   209 	nqld->l.flags &= ~VL_RESORT;
   210 }
   210 }
   211 
   211 
   212 /* Uses network_ql_d (network_d, querystr_d and list_d) WP macro */
   212 /** Enum for NetworkGameWindow, referring to _network_game_window_widgets */
       
   213 enum NetworkGameWindowWidgets {
       
   214 	NGWW_CLOSE    = 0,  ///< Close 'X' button
       
   215 	NGWW_CONN_TXT = 4,  ///< 'Connection' droplist
       
   216 	NGWW_CONN_BTN = 5,  ///< 'Connection' droplist button
       
   217 	NGWW_PLAYER   = 6,  ///< Panel with editbox to set player name
       
   218 
       
   219 	NGWW_NAME     = 7,  ///< 'Name' button
       
   220 	NGWW_CLIENTS,       ///< 'Clients' button
       
   221 	NGWW_INFO,          ///< Third button in the game list panel
       
   222 
       
   223 	NGWW_MATRIX   = 10, ///< Panel with list of games
       
   224 
       
   225 	NGWW_DETAILS  = 12, ///< Panel with game details
       
   226 	NGWW_JOIN     = 13, ///< 'Join game' button
       
   227 	NGWW_REFRESH  = 14, ///< 'Refresh server' button
       
   228 	NGWW_NEWGRF   = 15, ///< 'NewGRF Settings' button
       
   229 
       
   230 	NGWW_FIND     = 16, ///< 'Find server' button
       
   231 	NGWW_ADD,           ///< 'Add server' button
       
   232 	NGWW_START,         ///< 'Start server' button
       
   233 	NGWW_CANCEL,        ///< 'Cancel' button
       
   234 };
       
   235 
       
   236 /**
       
   237  * Handler of actions done in the NetworkStartServer window
       
   238  *
       
   239  * @param w pointer to the Window structure
       
   240  * @param e pointer to window event
       
   241  * @note    Uses network_ql_d (network_d, querystr_d and list_d) WP macro
       
   242  * @see     struct _network_game_window_widgets
       
   243  * @see     enum NetworkGameWindowWidgets
       
   244  */
       
   245 
   213 static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
   246 static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
   214 {
   247 {
   215 	network_d *nd = &WP(w, network_ql_d).n;
   248 	network_d *nd = &WP(w, network_ql_d).n;
   216 	list_d *ld = &WP(w, network_ql_d).l;
   249 	list_d *ld = &WP(w, network_ql_d).l;
   217 
   250 
   218 	switch (e->event) {
   251 	switch (e->event) {
   219 	case WE_CREATE: /* Focus input box */
   252 	case WE_CREATE: // Focus input box
   220 		w->vscroll.cap = 13;
   253 		w->vscroll.cap = 13;
   221 		w->resize.step_height = NET_PRC__SIZE_OF_ROW;
   254 		w->resize.step_height = NET_PRC__SIZE_OF_ROW;
   222 
   255 
   223 		nd->field = 3;
   256 		nd->field = NGWW_PLAYER;
   224 		nd->server = NULL;
   257 		nd->server = NULL;
   225 
   258 
   226 		WP(w, network_ql_d).sort_list = NULL;
   259 		WP(w, network_ql_d).sort_list = NULL;
   227 		ld->flags = VL_REBUILD | (_ng_sorting.order ? VL_DESC : VL_NONE);
   260 		ld->flags = VL_REBUILD | (_ng_sorting.order ? VL_DESC : VL_NONE);
   228 		ld->sort_type = _ng_sorting.criteria;
   261 		ld->sort_type = _ng_sorting.criteria;
   236 			BuildNetworkGameList(&WP(w, network_ql_d));
   269 			BuildNetworkGameList(&WP(w, network_ql_d));
   237 			SetVScrollCount(w, ld->list_length);
   270 			SetVScrollCount(w, ld->list_length);
   238 		}
   271 		}
   239 		if (ld->flags & VL_RESORT) SortNetworkGameList(&WP(w, network_ql_d));
   272 		if (ld->flags & VL_RESORT) SortNetworkGameList(&WP(w, network_ql_d));
   240 
   273 
   241 		SetWindowWidgetDisabledState(w, 17, sel == NULL);
   274 		/* 'Refresh' button invisible if no server selected */
   242 		/* Join Button disabling conditions */
   275 		SetWindowWidgetDisabledState(w, NGWW_REFRESH, sel == NULL);
   243 		SetWindowWidgetDisabledState(w, 16, sel == NULL || // no Selected Server
   276 		/* 'Join' button disabling conditions */
       
   277 		SetWindowWidgetDisabledState(w, NGWW_JOIN, sel == NULL || // no Selected Server
   244 				!sel->online || // Server offline
   278 				!sel->online || // Server offline
   245 				sel->info.clients_on >= sel->info.clients_max || // Server full
   279 				sel->info.clients_on >= sel->info.clients_max || // Server full
   246 				!sel->info.compatible); // Revision mismatch
   280 				!sel->info.compatible); // Revision mismatch
   247 
   281 
   248 		SetWindowWidgetHiddenState(w, 18, sel == NULL ||
   282 		/* 'NewGRF Settings' button invisible if no NewGRF is used */
       
   283 		SetWindowWidgetHiddenState(w, NGWW_NEWGRF, sel == NULL ||
   249 				!sel->online ||
   284 				!sel->online ||
   250 				sel->info.grfconfig == NULL);
   285 				sel->info.grfconfig == NULL);
   251 
   286 
   252 		SetDParam(0, 0x00);
   287 		SetDParam(0, 0x00);
   253 		SetDParam(1, _lan_internet_types_dropdown[_network_lan_internet]);
   288 		SetDParam(1, _lan_internet_types_dropdown[_network_lan_internet]);
   254 		DrawWindowWidgets(w);
   289 		DrawWindowWidgets(w);
   255 
   290 
   256 		DrawEditBox(w, &WP(w, network_ql_d).q, 3);
   291 		/* Edit box to set player name */
   257 
   292 		DrawEditBox(w, &WP(w, network_ql_d).q, NGWW_PLAYER);
   258 		DrawString(9, 23, STR_NETWORK_CONNECTION, TC_GOLD);
   293 
   259 		DrawString(w->widget[3].left - 100, 23, STR_NETWORK_PLAYER_NAME, TC_GOLD);
   294 		DrawString(w->widget[NGWW_PLAYER].left - 100, 23, STR_NETWORK_PLAYER_NAME, TC_GOLD);
   260 
   295 
   261 		/* Sort based on widgets: name, clients, compatibility */
   296 		/* Sort based on widgets: name, clients, compatibility */
   262 		switch (ld->sort_type) {
   297 		switch (ld->sort_type) {
   263 			case 6 - 6: DoDrawString(arrow, w->widget[6].right - 10, 42, TC_BLACK); break;
   298 			case NGWW_NAME    - NGWW_NAME: DoDrawString(arrow, w->widget[NGWW_NAME].right    - 10, 42, TC_BLACK); break;
   264 			case 7 - 6: DoDrawString(arrow, w->widget[7].right - 10, 42, TC_BLACK); break;
   299 			case NGWW_CLIENTS - NGWW_NAME: DoDrawString(arrow, w->widget[NGWW_CLIENTS].right - 10, 42, TC_BLACK); break;
   265 			case 8 - 6: DoDrawString(arrow, w->widget[8].right - 10, 42, TC_BLACK); break;
   300 			case NGWW_INFO    - NGWW_NAME: DoDrawString(arrow, w->widget[NGWW_INFO].right    - 10, 42, TC_BLACK); break;
   266 		}
   301 		}
   267 
   302 
   268 		{ // draw list of games
   303 		{ // draw list of games
   269 			uint16 y = NET_PRC__OFFSET_TOP_WIDGET + 3;
   304 			uint16 y = NET_PRC__OFFSET_TOP_WIDGET + 3;
   270 			int32 n = 0;
   305 			int32 n = 0;
   271 			int32 pos = w->vscroll.pos;
   306 			int32 pos = w->vscroll.pos;
   272 			uint max_name_width = w->widget[6].right - w->widget[6].left - 5;
   307 			uint max_name_width = w->widget[NGWW_NAME].right - w->widget[NGWW_NAME].left - 5;
   273 			const NetworkGameList *cur_item = _network_game_list;
   308 			const NetworkGameList *cur_item = _network_game_list;
   274 
   309 
   275 			while (pos > 0 && cur_item != NULL) {
   310 			while (pos > 0 && cur_item != NULL) {
   276 				pos--;
   311 				pos--;
   277 				cur_item = cur_item->next;
   312 				cur_item = cur_item->next;
   278 			}
   313 			}
   279 
   314 
   280 			while (cur_item != NULL) {
   315 			while (cur_item != NULL) {
   281 				// show highlighted item with a different colour
   316 				/* show highlighted item with a different colour */
   282 				if (cur_item == sel) GfxFillRect(w->widget[6].left + 1, y - 2, w->widget[8].right - 1, y + 9, 10);
   317 				if (cur_item == sel) GfxFillRect(w->widget[NGWW_NAME].left + 1, y - 2, w->widget[NGWW_INFO].right - 1, y + 9, 10);
   283 
   318 
   284 				SetDParamStr(0, cur_item->info.server_name);
   319 				SetDParamStr(0, cur_item->info.server_name);
   285 				DrawStringTruncated(w->widget[6].left + 5, y, STR_02BD, TC_BLACK, max_name_width);
   320 				DrawStringTruncated(w->widget[NGWW_NAME].left + 5, y, STR_02BD, TC_BLACK, max_name_width);
   286 
   321 
   287 				SetDParam(0, cur_item->info.clients_on);
   322 				SetDParam(0, cur_item->info.clients_on);
   288 				SetDParam(1, cur_item->info.clients_max);
   323 				SetDParam(1, cur_item->info.clients_max);
   289 				SetDParam(2, cur_item->info.companies_on);
   324 				SetDParam(2, cur_item->info.companies_on);
   290 				SetDParam(3, cur_item->info.companies_max);
   325 				SetDParam(3, cur_item->info.companies_max);
   291 				DrawStringCentered(w->widget[7].left + 39, y, STR_NETWORK_GENERAL_ONLINE, TC_GOLD);
   326 				DrawStringCentered(w->widget[NGWW_CLIENTS].left + 39, y, STR_NETWORK_GENERAL_ONLINE, TC_GOLD);
   292 
   327 
   293 				// only draw icons if the server is online
   328 				/* only draw icons if the server is online */
   294 				if (cur_item->online) {
   329 				if (cur_item->online) {
   295 					// draw a lock if the server is password protected.
   330 					/* draw a lock if the server is password protected */
   296 					if (cur_item->info.use_password) DrawSprite(SPR_LOCK, PAL_NONE, w->widget[8].left + 5, y - 1);
   331 					if (cur_item->info.use_password) DrawSprite(SPR_LOCK, PAL_NONE, w->widget[NGWW_INFO].left + 5, y - 1);
   297 
   332 
   298 					// draw red or green icon, depending on compatibility with server.
   333 					/* draw red or green icon, depending on compatibility with server */
   299 					DrawSprite(SPR_BLOT, (cur_item->info.compatible ? PALETTE_TO_GREEN : (cur_item->info.version_compatible ? PALETTE_TO_YELLOW : PALETTE_TO_RED)), w->widget[8].left + 15, y);
   334 					DrawSprite(SPR_BLOT, (cur_item->info.compatible ? PALETTE_TO_GREEN : (cur_item->info.version_compatible ? PALETTE_TO_YELLOW : PALETTE_TO_RED)), w->widget[NGWW_INFO].left + 15, y);
   300 
   335 
   301 					// draw flag according to server language
   336 					/* draw flag according to server language */
   302 					DrawSprite(SPR_FLAGS_BASE + cur_item->info.server_lang, PAL_NONE, w->widget[8].left + 25, y);
   337 					DrawSprite(SPR_FLAGS_BASE + cur_item->info.server_lang, PAL_NONE, w->widget[NGWW_INFO].left + 25, y);
   303 				}
   338 				}
   304 
   339 
   305 				cur_item = cur_item->next;
   340 				cur_item = cur_item->next;
   306 				y += NET_PRC__SIZE_OF_ROW;
   341 				y += NET_PRC__SIZE_OF_ROW;
   307 				if (++n == w->vscroll.cap) break; // max number of games in the window
   342 				if (++n == w->vscroll.cap) break; // max number of games in the window
   308 			}
   343 			}
   309 		}
   344 		}
   310 
   345 
   311 		/* Draw the right menu */
   346 		/* Draw the right menu */
   312 		GfxFillRect(w->widget[15].left + 1, 43, w->widget[15].right - 1, 92, 157);
   347 		GfxFillRect(w->widget[NGWW_DETAILS].left + 1, 43, w->widget[NGWW_DETAILS].right - 1, 92, 157);
   313 		if (sel == NULL) {
   348 		if (sel == NULL) {
   314 			DrawStringCentered(w->widget[15].left + 115, 58, STR_NETWORK_GAME_INFO, TC_FROMSTRING);
   349 			DrawStringCentered(w->widget[NGWW_DETAILS].left + 115, 58, STR_NETWORK_GAME_INFO, TC_FROMSTRING);
   315 		} else if (!sel->online) {
   350 		} else if (!sel->online) {
   316 			SetDParamStr(0, sel->info.server_name);
   351 			SetDParamStr(0, sel->info.server_name);
   317 			DrawStringCentered(w->widget[15].left + 115, 68, STR_ORANGE, TC_FROMSTRING); // game name
   352 			DrawStringCentered(w->widget[NGWW_DETAILS].left + 115, 68, STR_ORANGE, TC_FROMSTRING); // game name
   318 
   353 
   319 			DrawStringCentered(w->widget[15].left + 115, 132, STR_NETWORK_SERVER_OFFLINE, TC_FROMSTRING); // server offline
   354 			DrawStringCentered(w->widget[NGWW_DETAILS].left + 115, 132, STR_NETWORK_SERVER_OFFLINE, TC_FROMSTRING); // server offline
   320 		} else { // show game info
   355 		} else { // show game info
   321 			uint16 y = 100;
   356 			uint16 y = 100;
   322 			const uint16 x = w->widget[15].left + 5;
   357 			const uint16 x = w->widget[NGWW_DETAILS].left + 5;
   323 
   358 
   324 			DrawStringCentered(w->widget[15].left + 115, 48, STR_NETWORK_GAME_INFO, TC_FROMSTRING);
   359 			DrawStringCentered(w->widget[NGWW_DETAILS].left + 115, 48, STR_NETWORK_GAME_INFO, TC_FROMSTRING);
   325 
   360 
   326 
   361 
   327 			SetDParamStr(0, sel->info.server_name);
   362 			SetDParamStr(0, sel->info.server_name);
   328 			DrawStringCenteredTruncated(w->widget[15].left, w->widget[15].right, 62, STR_ORANGE, TC_BLACK); // game name
   363 			DrawStringCenteredTruncated(w->widget[NGWW_DETAILS].left, w->widget[NGWW_DETAILS].right, 62, STR_ORANGE, TC_BLACK); // game name
   329 
   364 
   330 			SetDParamStr(0, sel->info.map_name);
   365 			SetDParamStr(0, sel->info.map_name);
   331 			DrawStringCenteredTruncated(w->widget[15].left, w->widget[15].right, 74, STR_02BD, TC_BLACK); // map name
   366 			DrawStringCenteredTruncated(w->widget[NGWW_DETAILS].left, w->widget[NGWW_DETAILS].right, 74, STR_02BD, TC_BLACK); // map name
   332 
   367 
   333 			SetDParam(0, sel->info.clients_on);
   368 			SetDParam(0, sel->info.clients_on);
   334 			SetDParam(1, sel->info.clients_max);
   369 			SetDParam(1, sel->info.clients_max);
   335 			SetDParam(2, sel->info.companies_on);
   370 			SetDParam(2, sel->info.companies_on);
   336 			SetDParam(3, sel->info.companies_max);
   371 			SetDParam(3, sel->info.companies_max);
   368 			y += 10;
   403 			y += 10;
   369 
   404 
   370 			y += 2;
   405 			y += 2;
   371 
   406 
   372 			if (!sel->info.compatible) {
   407 			if (!sel->info.compatible) {
   373 				DrawStringCentered(w->widget[15].left + 115, y, sel->info.version_compatible ? STR_NETWORK_GRF_MISMATCH : STR_NETWORK_VERSION_MISMATCH, TC_FROMSTRING); // server mismatch
   408 				DrawStringCentered(w->widget[NGWW_DETAILS].left + 115, y, sel->info.version_compatible ? STR_NETWORK_GRF_MISMATCH : STR_NETWORK_VERSION_MISMATCH, TC_FROMSTRING); // server mismatch
   374 			} else if (sel->info.clients_on == sel->info.clients_max) {
   409 			} else if (sel->info.clients_on == sel->info.clients_max) {
   375 				// Show: server full, when clients_on == clients_max
   410 				/* Show: server full, when clients_on == clients_max */
   376 				DrawStringCentered(w->widget[15].left + 115, y, STR_NETWORK_SERVER_FULL, TC_FROMSTRING); // server full
   411 				DrawStringCentered(w->widget[NGWW_DETAILS].left + 115, y, STR_NETWORK_SERVER_FULL, TC_FROMSTRING); // server full
   377 			} else if (sel->info.use_password) {
   412 			} else if (sel->info.use_password) {
   378 				DrawStringCentered(w->widget[15].left + 115, y, STR_NETWORK_PASSWORD, TC_FROMSTRING); // password warning
   413 				DrawStringCentered(w->widget[NGWW_DETAILS].left + 115, y, STR_NETWORK_PASSWORD, TC_FROMSTRING); // password warning
   379 			}
   414 			}
   380 
   415 
   381 			y += 10;
   416 			y += 10;
   382 		}
   417 		}
   383 	} break;
   418 	} break;
   384 
   419 
   385 	case WE_CLICK:
   420 	case WE_CLICK:
   386 		nd->field = e->we.click.widget;
   421 		nd->field = e->we.click.widget;
   387 		switch (e->we.click.widget) {
   422 		switch (e->we.click.widget) {
   388 		case 14: // Cancel button
   423 		case NGWW_CANCEL: // Cancel button
   389 			DeleteWindowById(WC_NETWORK_WINDOW, 0);
   424 			DeleteWindowById(WC_NETWORK_WINDOW, 0);
   390 			break;
   425 			break;
   391 		case 4: case 5:
   426 		case NGWW_CONN_TXT: case NGWW_CONN_BTN: // 'Connection' droplist
   392 			ShowDropDownMenu(w, _lan_internet_types_dropdown, _network_lan_internet, 5, 0, 0); // do it for widget 5
   427 			ShowDropDownMenu(w, _lan_internet_types_dropdown, _network_lan_internet, NGWW_CONN_BTN, 0, 0); // do it for widget NSSW_CONN_BTN
   393 			break;
   428 			break;
   394 		case 6: /* Sort by name */
   429 		case NGWW_NAME: // Sort by name
   395 		case 7: /* Sort by connected clients */
   430 		case NGWW_CLIENTS: // Sort by connected clients
   396 		case 8: /* Connectivity (green dot) */
   431 		case NGWW_INFO: // Connectivity (green dot)
   397 			if (ld->sort_type == e->we.click.widget - 6) ld->flags ^= VL_DESC;
   432 			if (ld->sort_type == e->we.click.widget - NGWW_NAME) ld->flags ^= VL_DESC;
   398 			ld->flags |= VL_RESORT;
   433 			ld->flags |= VL_RESORT;
   399 			ld->sort_type = e->we.click.widget - 6;
   434 			ld->sort_type = e->we.click.widget - NGWW_NAME;
   400 
   435 
   401 			_ng_sorting.order = !!(ld->flags & VL_DESC);
   436 			_ng_sorting.order = !!(ld->flags & VL_DESC);
   402 			_ng_sorting.criteria = ld->sort_type;
   437 			_ng_sorting.criteria = ld->sort_type;
   403 			SetWindowDirty(w);
   438 			SetWindowDirty(w);
   404 			break;
   439 			break;
   405 		case 9: { /* Matrix to show networkgames */
   440 		case NGWW_MATRIX: { // Matrix to show networkgames
   406 			NetworkGameList *cur_item;
   441 			NetworkGameList *cur_item;
   407 			uint32 id_v = (e->we.click.pt.y - NET_PRC__OFFSET_TOP_WIDGET) / NET_PRC__SIZE_OF_ROW;
   442 			uint32 id_v = (e->we.click.pt.y - NET_PRC__OFFSET_TOP_WIDGET) / NET_PRC__SIZE_OF_ROW;
   408 
   443 
   409 			if (id_v >= w->vscroll.cap) return; // click out of bounds
   444 			if (id_v >= w->vscroll.cap) return; // click out of bounds
   410 			id_v += w->vscroll.pos;
   445 			id_v += w->vscroll.pos;
   413 			for (; id_v > 0 && cur_item != NULL; id_v--) cur_item = cur_item->next;
   448 			for (; id_v > 0 && cur_item != NULL; id_v--) cur_item = cur_item->next;
   414 
   449 
   415 			nd->server = cur_item;
   450 			nd->server = cur_item;
   416 			SetWindowDirty(w);
   451 			SetWindowDirty(w);
   417 		} break;
   452 		} break;
   418 		case 11: /* Find server automatically */
   453 		case NGWW_FIND: // Find server automatically
   419 			switch (_network_lan_internet) {
   454 			switch (_network_lan_internet) {
   420 				case 0: NetworkUDPSearchGame(); break;
   455 				case 0: NetworkUDPSearchGame(); break;
   421 				case 1: NetworkUDPQueryMasterServer(); break;
   456 				case 1: NetworkUDPQueryMasterServer(); break;
   422 			}
   457 			}
   423 			break;
   458 			break;
   424 		case 12: { // Add a server
   459 		case NGWW_ADD: { // Add a server
   425 				ShowQueryString(
   460 			ShowQueryString(
   426 				BindCString(_network_default_ip),
   461 				BindCString(_network_default_ip),
   427 				STR_NETWORK_ENTER_IP,
   462 				STR_NETWORK_ENTER_IP,
   428 				31 | 0x1000,  // maximum number of characters OR
   463 				31 | 0x1000,  // maximum number of characters OR
   429 				250, // characters up to this width pixels, whichever is satisfied first
   464 				250, // characters up to this width pixels, whichever is satisfied first
   430 				w, CS_ALPHANUMERAL);
   465 				w, CS_ALPHANUMERAL);
   431 		} break;
   466 		} break;
   432 		case 13: /* Start server */
   467 		case NGWW_START: // Start server
   433 			ShowNetworkStartServerWindow();
   468 			ShowNetworkStartServerWindow();
   434 			break;
   469 			break;
   435 		case 16: /* Join Game */
   470 		case NGWW_JOIN: // Join Game
   436 			if (nd->server != NULL) {
   471 			if (nd->server != NULL) {
   437 				snprintf(_network_last_host, sizeof(_network_last_host), "%s", inet_ntoa(*(struct in_addr *)&nd->server->ip));
   472 				snprintf(_network_last_host, sizeof(_network_last_host), "%s", inet_ntoa(*(struct in_addr *)&nd->server->ip));
   438 				_network_last_port = nd->server->port;
   473 				_network_last_port = nd->server->port;
   439 				ShowNetworkLobbyWindow(nd->server);
   474 				ShowNetworkLobbyWindow(nd->server);
   440 			}
   475 			}
   441 			break;
   476 			break;
   442 		case 17: // Refresh
   477 		case NGWW_REFRESH: // Refresh
   443 			if (nd->server != NULL)
   478 			if (nd->server != NULL)
   444 				NetworkUDPQueryServer(nd->server->info.hostname, nd->server->port);
   479 				NetworkUDPQueryServer(nd->server->info.hostname, nd->server->port);
   445 			break;
   480 			break;
   446 		case 18: // NewGRF Settings
   481 		case NGWW_NEWGRF: // NewGRF Settings
   447 			if (nd->server != NULL) ShowNewGRFSettings(false, false, false, &nd->server->info.grfconfig);
   482 			if (nd->server != NULL) ShowNewGRFSettings(false, false, false, &nd->server->info.grfconfig);
   448 			break;
   483 			break;
   449 
   484 
   450 	} break;
   485 	} break;
   451 
   486 
   452 	case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
   487 	case WE_DROPDOWN_SELECT: // we have selected a dropdown item in the list
   453 		switch (e->we.dropdown.button) {
   488 		switch (e->we.dropdown.button) {
   454 			case 5:
   489 			case NGWW_CONN_BTN:
   455 				_network_lan_internet = e->we.dropdown.index;
   490 				_network_lan_internet = e->we.dropdown.index;
   456 				break;
   491 				break;
       
   492 			default:
       
   493 				NOT_REACHED();
   457 		}
   494 		}
   458 
   495 
   459 		SetWindowDirty(w);
   496 		SetWindowDirty(w);
   460 		break;
   497 		break;
   461 
   498 
   462 	case WE_MOUSELOOP:
   499 	case WE_MOUSELOOP:
   463 		if (nd->field == 3) HandleEditBox(w, &WP(w, network_ql_d).q, 3);
   500 		if (nd->field == NGWW_PLAYER) HandleEditBox(w, &WP(w, network_ql_d).q, NGWW_PLAYER);
   464 		break;
   501 		break;
   465 
   502 
   466 	case WE_MESSAGE:
   503 	case WE_MESSAGE:
   467 		if (e->we.message.msg != 0) nd->server = NULL;
   504 		if (e->we.message.msg != 0) nd->server = NULL;
   468 		ld->flags |= VL_REBUILD;
   505 		ld->flags |= VL_REBUILD;
   469 		SetWindowDirty(w);
   506 		SetWindowDirty(w);
   470 		break;
   507 		break;
   471 
   508 
   472 	case WE_KEYPRESS:
   509 	case WE_KEYPRESS:
   473 		if (nd->field != 3) {
   510 		if (nd->field != NGWW_PLAYER) {
   474 			if (nd->server != NULL) {
   511 			if (nd->server != NULL) {
   475 				if (e->we.keypress.keycode == WKC_DELETE) { /* Press 'delete' to remove servers */
   512 				if (e->we.keypress.keycode == WKC_DELETE) { // Press 'delete' to remove servers
   476 					NetworkGameListRemoveItem(nd->server);
   513 					NetworkGameListRemoveItem(nd->server);
   477 					NetworkRebuildHostList();
   514 					NetworkRebuildHostList();
   478 					nd->server = NULL;
   515 					nd->server = NULL;
   479 				}
   516 				}
   480 			}
   517 			}
   481 			break;
   518 			break;
   482 		}
   519 		}
   483 
   520 
   484 		if (HandleEditBoxKey(w, &WP(w, network_ql_d).q, 3, e) == 1) break; // enter pressed
   521 		if (HandleEditBoxKey(w, &WP(w, network_ql_d).q, NGWW_PLAYER, e) == 1) break; // enter pressed
   485 
   522 
   486 		// The name is only allowed when it starts with a letter!
   523 		/* The name is only allowed when it starts with a letter! */
   487 		if (_edit_str_buf[0] != '\0' && _edit_str_buf[0] != ' ') {
   524 		if (_edit_str_buf[0] != '\0' && _edit_str_buf[0] != ' ') {
   488 			ttd_strlcpy(_network_player_name, _edit_str_buf, lengthof(_network_player_name));
   525 			ttd_strlcpy(_network_player_name, _edit_str_buf, lengthof(_network_player_name));
   489 		} else {
   526 		} else {
   490 			ttd_strlcpy(_network_player_name, "Player", lengthof(_network_player_name));
   527 			ttd_strlcpy(_network_player_name, "Player", lengthof(_network_player_name));
   491 		}
   528 		}
   498 		break;
   535 		break;
   499 
   536 
   500 	case WE_RESIZE: {
   537 	case WE_RESIZE: {
   501 		w->vscroll.cap += e->we.sizing.diff.y / (int)w->resize.step_height;
   538 		w->vscroll.cap += e->we.sizing.diff.y / (int)w->resize.step_height;
   502 
   539 
   503 		w->widget[9].data = (w->vscroll.cap << 8) + 1;
   540 		w->widget[NGWW_MATRIX].data = (w->vscroll.cap << 8) + 1;
   504 
   541 
   505 		int widget_width = w->widget[11].right - w->widget[11].left;
   542 		int widget_width = w->widget[NGWW_FIND].right - w->widget[NGWW_FIND].left;
   506 		int space = (w->width - 4 * widget_width - 25) / 3;
   543 		int space = (w->width - 4 * widget_width - 25) / 3;
   507 
   544 
   508 		int offset = 10;
   545 		int offset = 10;
   509 		for (uint i = 0; i < 4; i++) {
   546 		for (uint i = 0; i < 4; i++) {
   510 			w->widget[11 + i].left  = offset;
   547 			w->widget[NGWW_FIND + i].left  = offset;
   511 			offset += widget_width;
   548 			offset += widget_width;
   512 			w->widget[11 + i].right = offset;
   549 			w->widget[NGWW_FIND + i].right = offset;
   513 			offset += space;
   550 			offset += space;
   514 		}
   551 		}
   515 	} break;
   552 	} break;
   516 
   553 
   517 	case WE_DESTROY: /* Nicely clean up the sort-list */
   554 	case WE_DESTROY: // Nicely clean up the sort-list
   518 		free(WP(w, network_ql_d).sort_list);
   555 		free(WP(w, network_ql_d).sort_list);
   519 		break;
   556 		break;
   520 	}
   557 	}
   521 }
   558 }
   522 
   559 
   523 static const Widget _network_game_window_widgets[] = {
   560 static const Widget _network_game_window_widgets[] = {
   524 {   WWT_CLOSEBOX,   RESIZE_NONE,   BGC,     0,    10,     0,    13, STR_00C5,                       STR_018B_CLOSE_WINDOW},
   561 /* TOP */
       
   562 {   WWT_CLOSEBOX,   RESIZE_NONE,   BGC,     0,    10,     0,    13, STR_00C5,                       STR_018B_CLOSE_WINDOW},            // NGWW_CLOSE
   525 {    WWT_CAPTION,   RESIZE_RIGHT,  BGC,    11,   449,     0,    13, STR_NETWORK_MULTIPLAYER,        STR_NULL},
   563 {    WWT_CAPTION,   RESIZE_RIGHT,  BGC,    11,   449,     0,    13, STR_NETWORK_MULTIPLAYER,        STR_NULL},
   526 {      WWT_PANEL,   RESIZE_RB,     BGC,     0,   449,    14,   263, 0x0,                            STR_NULL},
   564 {      WWT_PANEL,   RESIZE_RB,     BGC,     0,   449,    14,   263, 0x0,                            STR_NULL},
   527 
   565 
       
   566 {       WWT_TEXT,   RESIZE_NONE,   BGC,     9,    85,    23,    35, STR_NETWORK_CONNECTION,         STR_NULL},
       
   567 {      WWT_INSET,   RESIZE_NONE,   BGC,    90,   181,    22,    33, STR_NETWORK_LAN_INTERNET_COMBO, STR_NETWORK_CONNECTION_TIP},       // NGWW_CONN_TXT
       
   568 {    WWT_TEXTBTN,   RESIZE_NONE,   BGC,   170,   180,    23,    32, STR_0225,                       STR_NETWORK_CONNECTION_TIP},       // NGWW_CONN_BTN
       
   569 
       
   570 {      WWT_PANEL,   RESIZE_LR,     BGC,   290,   440,    22,    33, 0x0,                            STR_NETWORK_ENTER_NAME_TIP},       // NGWW_PLAYER
       
   571 
   528 /* LEFT SIDE */
   572 /* LEFT SIDE */
   529 {      WWT_PANEL,   RESIZE_LR,     BGC,   290,   440,    22,    33, 0x0,                            STR_NETWORK_ENTER_NAME_TIP},
   573 { WWT_PUSHTXTBTN,   RESIZE_RIGHT,  BTC,    10,    70,    42,    53, STR_NETWORK_GAME_NAME,          STR_NETWORK_GAME_NAME_TIP},        // NGWW_NAME
   530 
   574 { WWT_PUSHTXTBTN,   RESIZE_LR,     BTC,    71,   150,    42,    53, STR_NETWORK_CLIENTS_CAPTION,    STR_NETWORK_CLIENTS_CAPTION_TIP},  // NGWW_CLIENTS
   531 {      WWT_INSET,   RESIZE_NONE,   BGC,    90,   181,    22,    33, STR_NETWORK_LAN_INTERNET_COMBO, STR_NETWORK_CONNECTION_TIP},
   575 { WWT_PUSHTXTBTN,   RESIZE_LR,     BTC,   151,   190,    42,    53, STR_EMPTY,                      STR_NETWORK_INFO_ICONS_TIP},       // NGWW_INFO
   532 {    WWT_TEXTBTN,   RESIZE_NONE,   BGC,   170,   180,    23,    32, STR_0225,                       STR_NETWORK_CONNECTION_TIP},
   576 
   533 
   577 {     WWT_MATRIX,   RESIZE_RB,     BGC,    10,   190,    54,   236, (13 << 8) + 1,                  STR_NETWORK_CLICK_GAME_TO_SELECT}, // NGWW_MATRIX
   534 { WWT_PUSHTXTBTN,   RESIZE_RIGHT,  BTC,    10,    70,    42,    53, STR_NETWORK_GAME_NAME,          STR_NETWORK_GAME_NAME_TIP},
   578 {  WWT_SCROLLBAR,   RESIZE_LRB,    BGC,   191,   202,    42,   236, 0x0,                            STR_0190_SCROLL_BAR_SCROLLS_LIST},
   535 { WWT_PUSHTXTBTN,   RESIZE_LR,     BTC,    71,   150,    42,    53, STR_NETWORK_CLIENTS_CAPTION,    STR_NETWORK_CLIENTS_CAPTION_TIP},
       
   536 { WWT_PUSHTXTBTN,   RESIZE_LR,     BTC,   151,   190,    42,    53, STR_EMPTY,                      STR_NETWORK_INFO_ICONS_TIP},
       
   537 
       
   538 {     WWT_MATRIX,   RESIZE_RB,     BGC,    10,   190,    54,   236, (13 << 8) + 1,                  STR_NETWORK_CLICK_GAME_TO_SELECT},
       
   539 {  WWT_SCROLLBAR,   RESIZE_LRB,    BGC,   191,   202,    42,   236, STR_NULL,                       STR_0190_SCROLL_BAR_SCROLLS_LIST},
       
   540 
       
   541 { WWT_PUSHTXTBTN,   RESIZE_TB,     BTC,    10,   110,   246,   257, STR_NETWORK_FIND_SERVER,        STR_NETWORK_FIND_SERVER_TIP},
       
   542 { WWT_PUSHTXTBTN,   RESIZE_TB,     BTC,   118,   218,   246,   257, STR_NETWORK_ADD_SERVER,         STR_NETWORK_ADD_SERVER_TIP},
       
   543 
   579 
   544 /* RIGHT SIDE */
   580 /* RIGHT SIDE */
   545 { WWT_PUSHTXTBTN,   RESIZE_TB,     BTC,   226,   326,   246,   257, STR_NETWORK_START_SERVER,       STR_NETWORK_START_SERVER_TIP},
   581 {      WWT_PANEL,   RESIZE_LRB,    BGC,   210,   440,    42,   236, 0x0,                            STR_NULL},                         // NGWW_DETAILS
   546 { WWT_PUSHTXTBTN,   RESIZE_TB,     BTC,   334,   434,   246,   257, STR_012E_CANCEL,                STR_NULL},
   582 
   547 
   583 { WWT_PUSHTXTBTN,   RESIZE_LRTB,   BTC,   215,   315,   215,   226, STR_NETWORK_JOIN_GAME,          STR_NULL},                         // NGWW_JOIN
   548 {      WWT_PANEL,   RESIZE_LRB,    BGC,   210,   440,    42,   236, 0x0,                            STR_NULL},
   584 { WWT_PUSHTXTBTN,   RESIZE_LRTB,   BTC,   330,   435,   215,   226, STR_NETWORK_REFRESH,            STR_NETWORK_REFRESH_TIP},          // NGWW_REFRESH
   549 
   585 
   550 { WWT_PUSHTXTBTN,   RESIZE_LRTB,   BTC,   215,   315,   215,   226, STR_NETWORK_JOIN_GAME,          STR_NULL},
   586 { WWT_PUSHTXTBTN,   RESIZE_LRTB,   BTC,   330,   435,   197,   208, STR_NEWGRF_SETTINGS_BUTTON,     STR_NULL},                         // NGWW_NEWGRF
   551 { WWT_PUSHTXTBTN,   RESIZE_LRTB,   BTC,   330,   435,   215,   226, STR_NETWORK_REFRESH,            STR_NETWORK_REFRESH_TIP},
   587 
   552 
   588 /* BOTTOM */
   553 { WWT_PUSHTXTBTN,   RESIZE_LRTB,   BTC,   330,   435,   197,   208, STR_NEWGRF_SETTINGS_BUTTON,     STR_NULL},
   589 { WWT_PUSHTXTBTN,   RESIZE_TB,     BTC,    10,   110,   246,   257, STR_NETWORK_FIND_SERVER,        STR_NETWORK_FIND_SERVER_TIP},      // NGWW_FIND
       
   590 { WWT_PUSHTXTBTN,   RESIZE_TB,     BTC,   118,   218,   246,   257, STR_NETWORK_ADD_SERVER,         STR_NETWORK_ADD_SERVER_TIP},       // NGWW_ADD
       
   591 { WWT_PUSHTXTBTN,   RESIZE_TB,     BTC,   226,   326,   246,   257, STR_NETWORK_START_SERVER,       STR_NETWORK_START_SERVER_TIP},     // NGWW_START
       
   592 { WWT_PUSHTXTBTN,   RESIZE_TB,     BTC,   334,   434,   246,   257, STR_012E_CANCEL,                STR_NULL},                         // NGWW_CANCEL
   554 
   593 
   555 {  WWT_RESIZEBOX,   RESIZE_LRTB,   BGC,   438,   449,   252,   263, 0x0,                            STR_RESIZE_BUTTON },
   594 {  WWT_RESIZEBOX,   RESIZE_LRTB,   BGC,   438,   449,   252,   263, 0x0,                            STR_RESIZE_BUTTON },
   556 
   595 
   557 {   WIDGETS_END},
   596 {   WIDGETS_END},
   558 };
   597 };