(svn r3441) - Feature: Allow the network game list to be sorted (by name/clients/compatibility ascending/descending)
This commit is contained in:
		
							
								
								
									
										221
									
								
								network_gui.c
									
									
									
									
									
								
							
							
						
						
									
										221
									
								
								network_gui.c
									
									
									
									
									
								
							@@ -28,18 +28,28 @@
 | 
				
			|||||||
#define MAX_QUERYSTR_LEN 64
 | 
					#define MAX_QUERYSTR_LEN 64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct network_d {
 | 
					typedef struct network_d {
 | 
				
			||||||
	byte company;
 | 
						byte company;            // select company in network lobby
 | 
				
			||||||
	byte field;
 | 
						byte field;              // select text-field in start-server and game-listing
 | 
				
			||||||
	NetworkGameList *server;
 | 
						NetworkGameList *server; // selected server in lobby and game-listing
 | 
				
			||||||
	FiosItem *map;
 | 
						FiosItem *map;           // selected map in start-server
 | 
				
			||||||
} network_d;
 | 
					} network_d;
 | 
				
			||||||
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(network_d));
 | 
					assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(network_d));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct network_q_d {
 | 
					typedef struct network_ql_d {
 | 
				
			||||||
	network_d n;
 | 
						network_d n;                 // see above; general stuff
 | 
				
			||||||
	querystr_d q;
 | 
						querystr_d q;                // text-input in start-server and game-listing
 | 
				
			||||||
} network_q_d;
 | 
						NetworkGameList **sort_list; // list of games (sorted)
 | 
				
			||||||
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(network_q_d));
 | 
						list_d l;                    // accompanying list-administration
 | 
				
			||||||
 | 
					} network_ql_d;
 | 
				
			||||||
 | 
					assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(network_ql_d));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct NetworkGameSorting {
 | 
				
			||||||
 | 
						bool order;    // Ascending / Descending
 | 
				
			||||||
 | 
						byte criteria; // Sorted by name/clients/connectivity
 | 
				
			||||||
 | 
					} NetworkGameSorting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Global to remember sorting after window has been closed */
 | 
				
			||||||
 | 
					static NetworkGameSorting _ng_sorting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char _edit_str_buf[MAX_QUERYSTR_LEN*2];
 | 
					static char _edit_str_buf[MAX_QUERYSTR_LEN*2];
 | 
				
			||||||
static void ShowNetworkStartServerWindow(void);
 | 
					static void ShowNetworkStartServerWindow(void);
 | 
				
			||||||
@@ -92,24 +102,136 @@ void UpdateNetworkGameWindow(bool unselect)
 | 
				
			|||||||
	Window* w = FindWindowById(WC_NETWORK_WINDOW, 0);
 | 
						Window* w = FindWindowById(WC_NETWORK_WINDOW, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (w != NULL) {
 | 
						if (w != NULL) {
 | 
				
			||||||
		if (unselect) WP(w, network_q_d).n.server = NULL;
 | 
							if (unselect) WP(w, network_ql_d).n.server = NULL;
 | 
				
			||||||
		SendWindowMessage(WC_NETWORK_WINDOW, 0, true, 0, 0);
 | 
							SendWindowMessage(WC_NETWORK_WINDOW, 0, true, 0, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* uses network_q_d (network_d and querystr_d) WP macro */
 | 
					static bool _internal_sort_order; // Used for Qsort order-flipping
 | 
				
			||||||
 | 
					typedef int CDECL NGameNameSortFunction(const void*, const void*);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Qsort function to sort by name. */
 | 
				
			||||||
 | 
					static int CDECL NGameNameSorter(const void *a, const void *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const NetworkGameList *cmp1 = *(const NetworkGameList**)a;
 | 
				
			||||||
 | 
						const NetworkGameList *cmp2 = *(const NetworkGameList**)b;
 | 
				
			||||||
 | 
						int r = stricmp(cmp1->info.server_name, cmp2->info.server_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (_internal_sort_order & 1) ? -r : r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Qsort function to sort by the amount of clients online on a
 | 
				
			||||||
 | 
					 * server. If the two servers have the same amount, the one with the
 | 
				
			||||||
 | 
					 * higher maximum is preferred. */
 | 
				
			||||||
 | 
					static int CDECL NGameClientSorter(const void *a, const void *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const NetworkGameList *cmp1 = *(const NetworkGameList**)a;
 | 
				
			||||||
 | 
						const NetworkGameList *cmp2 = *(const NetworkGameList**)b;
 | 
				
			||||||
 | 
						/* Reverse as per default we are interested in most-clients first */
 | 
				
			||||||
 | 
						int r = cmp2->info.clients_on - cmp1->info.clients_on;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (r == 0) r = cmp1->info.clients_max - cmp2->info.clients_max;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (_internal_sort_order & 1) ? -r : r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Qsort function to sort by joinability. If both servers are the
 | 
				
			||||||
 | 
					 * same, prefer the non-passworded server first. */
 | 
				
			||||||
 | 
					static int CDECL NGameAllowedSorter(const void *a, const void *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const NetworkGameList *cmp1 = *(const NetworkGameList**)a;
 | 
				
			||||||
 | 
						const NetworkGameList *cmp2 = *(const NetworkGameList**)b;
 | 
				
			||||||
 | 
						/* Reverse default as we are interested in compatible clients first */
 | 
				
			||||||
 | 
						int r = cmp2->info.compatible - cmp1->info.compatible;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (r == 0) r = cmp1->info.use_password - cmp2->info.use_password;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (_internal_sort_order & 1) ? -r : r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static NGameNameSortFunction* const _ngame_sorter[] = {
 | 
				
			||||||
 | 
						&NGameNameSorter,
 | 
				
			||||||
 | 
						&NGameClientSorter,
 | 
				
			||||||
 | 
						&NGameAllowedSorter
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** (Re)build the network game list as its amount has changed because
 | 
				
			||||||
 | 
					 * an item has been added or deleted for example
 | 
				
			||||||
 | 
					 * @param ngl list_d struct that contains all necessary information for sorting */
 | 
				
			||||||
 | 
					static void BuildNetworkGameList(network_ql_d *nqld)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						NetworkGameList *ngl_temp;
 | 
				
			||||||
 | 
						uint n = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(nqld->l.flags & VL_REBUILD)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Count the number of games in the list */
 | 
				
			||||||
 | 
						for (ngl_temp = _network_game_list; ngl_temp != NULL; ngl_temp = ngl_temp->next) n++;
 | 
				
			||||||
 | 
						if (n == 0) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Create temporary array of games to use for listing */
 | 
				
			||||||
 | 
						free(nqld->sort_list);
 | 
				
			||||||
 | 
						nqld->sort_list = malloc(n * sizeof(nqld->sort_list[0]));
 | 
				
			||||||
 | 
						if (nqld->sort_list == NULL) error("Could not allocate memory for the network-game-sorting-list");
 | 
				
			||||||
 | 
						nqld->l.list_length = n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (n = 0, ngl_temp = _network_game_list; ngl_temp != NULL; ngl_temp = ngl_temp->next) {
 | 
				
			||||||
 | 
							nqld->sort_list[n++] = ngl_temp;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Force resort */
 | 
				
			||||||
 | 
						nqld->l.flags &= ~VL_REBUILD;
 | 
				
			||||||
 | 
						nqld->l.flags |= VL_RESORT;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void SortNetworkGameList(network_ql_d *nqld)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						NetworkGameList *item;
 | 
				
			||||||
 | 
						uint i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(nqld->l.flags & VL_RESORT)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_internal_sort_order = nqld->l.flags & VL_DESC;
 | 
				
			||||||
 | 
						qsort(nqld->sort_list, nqld->l.list_length, sizeof(nqld->sort_list[0]), _ngame_sorter[nqld->l.sort_type]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* After sorting ngl->sort_list contains the sorted items. Put these back
 | 
				
			||||||
 | 
						 * into the original list. Basically nothing has changed, we are only
 | 
				
			||||||
 | 
						 * shuffling the ->next pointers */
 | 
				
			||||||
 | 
						_network_game_list = nqld->sort_list[0];
 | 
				
			||||||
 | 
						for (item = _network_game_list, i = 1; i != nqld->l.list_length; i++) {
 | 
				
			||||||
 | 
							item->next = nqld->sort_list[i];
 | 
				
			||||||
 | 
							item = item->next;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						item->next = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nqld->l.flags &= ~VL_RESORT;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Uses network_ql_d (network_d, querystr_d and list_d) WP macro */
 | 
				
			||||||
static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
 | 
					static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	network_d *nd = &WP(w, network_q_d).n;
 | 
						network_d *nd = &WP(w, network_ql_d).n;
 | 
				
			||||||
 | 
						list_d *ld = &WP(w, network_ql_d).l;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (e->event) {
 | 
						switch (e->event) {
 | 
				
			||||||
	case WE_CREATE: /* focus input box */
 | 
						case WE_CREATE: /* Focus input box */
 | 
				
			||||||
		nd->field = 3;
 | 
							nd->field = 3;
 | 
				
			||||||
		nd->server = NULL;
 | 
							nd->server = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							WP(w, network_ql_d).sort_list = NULL;
 | 
				
			||||||
 | 
							ld->flags = VL_REBUILD | (_ng_sorting.order << (VL_DESC - 1));
 | 
				
			||||||
 | 
							ld->sort_type = _ng_sorting.criteria;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case WE_PAINT: {
 | 
						case WE_PAINT: {
 | 
				
			||||||
		const NetworkGameList *sel = nd->server;
 | 
							const NetworkGameList *sel = nd->server;
 | 
				
			||||||
 | 
							const char *arrow = (ld->flags & VL_DESC) ? DOWNARROW : UPARROW;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (ld->flags & VL_REBUILD) {
 | 
				
			||||||
 | 
								BuildNetworkGameList(&WP(w, network_ql_d));
 | 
				
			||||||
 | 
								SetVScrollCount(w, ld->list_length);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (ld->flags & VL_RESORT) SortNetworkGameList(&WP(w, network_ql_d));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		w->disabled_state = 0;
 | 
							w->disabled_state = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -128,11 +250,18 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
 | 
				
			|||||||
		SetDParam(7, _lan_internet_types_dropdown[_network_lan_internet]);
 | 
							SetDParam(7, _lan_internet_types_dropdown[_network_lan_internet]);
 | 
				
			||||||
		DrawWindowWidgets(w);
 | 
							DrawWindowWidgets(w);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		DrawEditBox(w, &WP(w, network_q_d).q, 3);
 | 
							DrawEditBox(w, &WP(w, network_ql_d).q, 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		DrawString(9, 23, STR_NETWORK_CONNECTION, 2);
 | 
							DrawString(9, 23, STR_NETWORK_CONNECTION, 2);
 | 
				
			||||||
		DrawString(210, 23, STR_NETWORK_PLAYER_NAME, 2);
 | 
							DrawString(210, 23, STR_NETWORK_PLAYER_NAME, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Sort based on widgets: name, clients, compatibility */
 | 
				
			||||||
 | 
							switch (ld->sort_type) {
 | 
				
			||||||
 | 
								case 6 - 6: DoDrawString(arrow, w->widget[6].right - 10, 42, 0x10); break;
 | 
				
			||||||
 | 
								case 7 - 6: DoDrawString(arrow, w->widget[7].right - 10, 42, 0x10); break;
 | 
				
			||||||
 | 
								case 8 - 6: DoDrawString(arrow, w->widget[8].right - 10, 42, 0x10); break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		{ // draw list of games
 | 
							{ // draw list of games
 | 
				
			||||||
			uint16 y = NET_PRC__OFFSET_TOP_WIDGET + 3;
 | 
								uint16 y = NET_PRC__OFFSET_TOP_WIDGET + 3;
 | 
				
			||||||
			int32 n = 0;
 | 
								int32 n = 0;
 | 
				
			||||||
@@ -259,6 +388,17 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
 | 
				
			|||||||
		case 4: case 5:
 | 
							case 4: case 5:
 | 
				
			||||||
			ShowDropDownMenu(w, _lan_internet_types_dropdown, _network_lan_internet, 5, 0, 0); // do it for widget 5
 | 
								ShowDropDownMenu(w, _lan_internet_types_dropdown, _network_lan_internet, 5, 0, 0); // do it for widget 5
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case 6: /* Sort by name */
 | 
				
			||||||
 | 
							case 7: /* Sort by connected clients */
 | 
				
			||||||
 | 
							case 8: /* Connectivity (green dot) */
 | 
				
			||||||
 | 
								if (ld->sort_type == e->click.widget - 6) ld->flags ^= VL_DESC;
 | 
				
			||||||
 | 
								ld->flags |= VL_RESORT;
 | 
				
			||||||
 | 
								ld->sort_type = e->click.widget - 6;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								_ng_sorting.order = !!(ld->flags & VL_DESC);
 | 
				
			||||||
 | 
								_ng_sorting.criteria = ld->sort_type;
 | 
				
			||||||
 | 
								SetWindowDirty(w);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		case 9: { /* Matrix to show networkgames */
 | 
							case 9: { /* Matrix to show networkgames */
 | 
				
			||||||
			NetworkGameList *cur_item;
 | 
								NetworkGameList *cur_item;
 | 
				
			||||||
			uint32 id_v = (e->click.pt.y - NET_PRC__OFFSET_TOP_WIDGET) / NET_PRC__SIZE_OF_ROW;
 | 
								uint32 id_v = (e->click.pt.y - NET_PRC__OFFSET_TOP_WIDGET) / NET_PRC__SIZE_OF_ROW;
 | 
				
			||||||
@@ -298,9 +438,8 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 17: // Refresh
 | 
							case 17: // Refresh
 | 
				
			||||||
			if (nd->server != NULL) {
 | 
								if (nd->server != NULL)
 | 
				
			||||||
				NetworkQueryServer(nd->server->info.hostname, nd->server->port, true);
 | 
									NetworkQueryServer(nd->server->info.hostname, nd->server->port, true);
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}	break;
 | 
						}	break;
 | 
				
			||||||
@@ -316,18 +455,13 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
 | 
				
			|||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case WE_MOUSELOOP:
 | 
						case WE_MOUSELOOP:
 | 
				
			||||||
		if (nd->field == 3) HandleEditBox(w, &WP(w, network_q_d).q, 3);
 | 
							if (nd->field == 3) HandleEditBox(w, &WP(w, network_ql_d).q, 3);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case WE_MESSAGE: {
 | 
						case WE_MESSAGE:
 | 
				
			||||||
		const NetworkGameList *nglist;
 | 
							ld->flags |= VL_REBUILD;
 | 
				
			||||||
		w->vscroll.count = 0;
 | 
					 | 
				
			||||||
		/* Game-count has changed, update scroll-count, scrollbar, and resort */
 | 
					 | 
				
			||||||
		for (nglist = _network_game_list; nglist != NULL; nglist = nglist->next) w->vscroll.count++;
 | 
					 | 
				
			||||||
		if (w->vscroll.count >= w->vscroll.cap && w->vscroll.pos > w->vscroll.count - w->vscroll.cap) w->vscroll.pos--;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		SetWindowDirty(w);
 | 
							SetWindowDirty(w);
 | 
				
			||||||
	}	break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case WE_KEYPRESS:
 | 
						case WE_KEYPRESS:
 | 
				
			||||||
		if (nd->field != 3) {
 | 
							if (nd->field != 3) {
 | 
				
			||||||
@@ -341,7 +475,7 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
 | 
				
			|||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (HandleEditBoxKey(w, &WP(w, network_q_d).q, 3, e) == 1) break; // enter pressed
 | 
							if (HandleEditBoxKey(w, &WP(w, network_ql_d).q, 3, e) == 1) break; // enter pressed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// The name is only allowed when it starts with a letter!
 | 
							// The name is only allowed when it starts with a letter!
 | 
				
			||||||
		if (_edit_str_buf[0] != '\0' && _edit_str_buf[0] != ' ') {
 | 
							if (_edit_str_buf[0] != '\0' && _edit_str_buf[0] != ' ') {
 | 
				
			||||||
@@ -356,6 +490,10 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
 | 
				
			|||||||
		NetworkAddServer(e->edittext.str);
 | 
							NetworkAddServer(e->edittext.str);
 | 
				
			||||||
		NetworkRebuildHostList();
 | 
							NetworkRebuildHostList();
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case WE_DESTROY: /* Nicely clean up the sort-list */
 | 
				
			||||||
 | 
							free(WP(w, network_ql_d).sort_list);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -420,7 +558,7 @@ void ShowNetworkGameWindow(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	w = AllocateWindowDesc(&_network_game_window_desc);
 | 
						w = AllocateWindowDesc(&_network_game_window_desc);
 | 
				
			||||||
	if (w != NULL) {
 | 
						if (w != NULL) {
 | 
				
			||||||
		querystr = &WP(w, network_q_d).q;
 | 
							querystr = &WP(w, network_ql_d).q;
 | 
				
			||||||
		ttd_strlcpy(_edit_str_buf, _network_player_name, MAX_QUERYSTR_LEN);
 | 
							ttd_strlcpy(_edit_str_buf, _network_player_name, MAX_QUERYSTR_LEN);
 | 
				
			||||||
		w->vscroll.cap = 12;
 | 
							w->vscroll.cap = 12;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -439,10 +577,10 @@ enum {
 | 
				
			|||||||
	NSSWND_ROWSIZE = 12
 | 
						NSSWND_ROWSIZE = 12
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* uses network_q_d (network_d and querystr_d) WP macro */
 | 
					/* Uses network_ql_d (network_d, querystr_d and list_d) WP macro */
 | 
				
			||||||
static void NetworkStartServerWindowWndProc(Window *w, WindowEvent *e)
 | 
					static void NetworkStartServerWindowWndProc(Window *w, WindowEvent *e)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	network_d *nd = &WP(w, network_q_d).n;
 | 
						network_d *nd = &WP(w, network_ql_d).n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (e->event) {
 | 
						switch (e->event) {
 | 
				
			||||||
	case WE_CREATE: /* focus input box */
 | 
						case WE_CREATE: /* focus input box */
 | 
				
			||||||
@@ -462,7 +600,7 @@ static void NetworkStartServerWindowWndProc(Window *w, WindowEvent *e)
 | 
				
			|||||||
		DrawWindowWidgets(w);
 | 
							DrawWindowWidgets(w);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		GfxFillRect(11, 63, 258, 215, 0xD7);
 | 
							GfxFillRect(11, 63, 258, 215, 0xD7);
 | 
				
			||||||
		DrawEditBox(w, &WP(w, network_q_d).q, 3);
 | 
							DrawEditBox(w, &WP(w, network_ql_d).q, 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		DrawString(10, 22, STR_NETWORK_NEW_GAME_NAME, 2);
 | 
							DrawString(10, 22, STR_NETWORK_NEW_GAME_NAME, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -569,15 +707,15 @@ static void NetworkStartServerWindowWndProc(Window *w, WindowEvent *e)
 | 
				
			|||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case WE_MOUSELOOP:
 | 
						case WE_MOUSELOOP:
 | 
				
			||||||
		if (nd->field == 3) HandleEditBox(w, &WP(w, network_q_d).q, 3);
 | 
							if (nd->field == 3) HandleEditBox(w, &WP(w, network_ql_d).q, 3);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case WE_KEYPRESS:
 | 
						case WE_KEYPRESS:
 | 
				
			||||||
		if (nd->field == 3) {
 | 
							if (nd->field == 3) {
 | 
				
			||||||
			if (HandleEditBoxKey(w, &WP(w, network_q_d).q, 3, e) == 1) break; // enter pressed
 | 
								if (HandleEditBoxKey(w, &WP(w, network_ql_d).q, 3, e) == 1) break; // enter pressed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			ttd_strlcpy(_network_server_name, WP(w, network_q_d).q.text.buf, sizeof(_network_server_name));
 | 
								ttd_strlcpy(_network_server_name, WP(w, network_ql_d).q.text.buf, sizeof(_network_server_name));
 | 
				
			||||||
			UpdateTextBufferSize(&WP(w, network_q_d).q.text);
 | 
								UpdateTextBufferSize(&WP(w, network_ql_d).q.text);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -638,11 +776,11 @@ static void ShowNetworkStartServerWindow(void)
 | 
				
			|||||||
	w->vscroll.cap = 9;
 | 
						w->vscroll.cap = 9;
 | 
				
			||||||
	w->vscroll.count = _fios_num+1;
 | 
						w->vscroll.count = _fios_num+1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	WP(w, network_q_d).q.text.caret = true;
 | 
						WP(w, network_ql_d).q.text.caret = true;
 | 
				
			||||||
	WP(w, network_q_d).q.text.maxlength = MAX_QUERYSTR_LEN - 1;
 | 
						WP(w, network_ql_d).q.text.maxlength = MAX_QUERYSTR_LEN - 1;
 | 
				
			||||||
	WP(w, network_q_d).q.text.maxwidth = 160;
 | 
						WP(w, network_ql_d).q.text.maxwidth = 160;
 | 
				
			||||||
	WP(w, network_q_d).q.text.buf = _edit_str_buf;
 | 
						WP(w, network_ql_d).q.text.buf = _edit_str_buf;
 | 
				
			||||||
	UpdateTextBufferSize(&WP(w, network_q_d).q.text);
 | 
						UpdateTextBufferSize(&WP(w, network_ql_d).q.text);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static byte NetworkLobbyFindCompanyIndex(byte pos)
 | 
					static byte NetworkLobbyFindCompanyIndex(byte pos)
 | 
				
			||||||
@@ -839,7 +977,8 @@ static const WindowDesc _network_lobby_window_desc = {
 | 
				
			|||||||
	NetworkLobbyWindowWndProc,
 | 
						NetworkLobbyWindowWndProc,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Show the networklobbywindow with the selected server
 | 
				
			||||||
 | 
					 * @param ngl Selected game pointer which is passed to the new window */
 | 
				
			||||||
static void ShowNetworkLobbyWindow(NetworkGameList *ngl)
 | 
					static void ShowNetworkLobbyWindow(NetworkGameList *ngl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	Window *w;
 | 
						Window *w;
 | 
				
			||||||
@@ -849,7 +988,7 @@ static void ShowNetworkLobbyWindow(NetworkGameList *ngl)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	w = AllocateWindowDesc(&_network_lobby_window_desc);
 | 
						w = AllocateWindowDesc(&_network_lobby_window_desc);
 | 
				
			||||||
	if (w != NULL) {
 | 
						if (w != NULL) {
 | 
				
			||||||
		WP(w, network_q_d).n.server = ngl;
 | 
							WP(w, network_ql_d).n.server = ngl;
 | 
				
			||||||
		strcpy(_edit_str_buf, "");
 | 
							strcpy(_edit_str_buf, "");
 | 
				
			||||||
		w->vscroll.cap = 10;
 | 
							w->vscroll.cap = 10;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								window.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								window.h
									
									
									
									
									
								
							@@ -431,9 +431,9 @@ typedef struct {
 | 
				
			|||||||
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(scroller_d));
 | 
					assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(scroller_d));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum VehicleListFlags {
 | 
					typedef enum VehicleListFlags {
 | 
				
			||||||
	VL_DESC    = 0x01,
 | 
						VL_DESC    = 0x01,  // sort descending or ascending
 | 
				
			||||||
	VL_RESORT  = 0x02,
 | 
						VL_RESORT  = 0x02,  // instruct the code to resort the list in the next loop
 | 
				
			||||||
	VL_REBUILD = 0x04
 | 
						VL_REBUILD = 0x04   // create sort-listing to use for qsort and friends
 | 
				
			||||||
} VehicleListFlags;
 | 
					} VehicleListFlags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct vehiclelist_d {
 | 
					typedef struct vehiclelist_d {
 | 
				
			||||||
@@ -445,6 +445,14 @@ typedef struct vehiclelist_d {
 | 
				
			|||||||
} vehiclelist_d;
 | 
					} vehiclelist_d;
 | 
				
			||||||
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vehiclelist_d));
 | 
					assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vehiclelist_d));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct list_d {
 | 
				
			||||||
 | 
						uint16 list_length;    // length of the list being sorted
 | 
				
			||||||
 | 
						byte sort_type;        // what criteria to sort on
 | 
				
			||||||
 | 
						VehicleListFlags flags;// used to control sorting/resorting/etc.
 | 
				
			||||||
 | 
						uint16 resort_timer;   // resort list after a given amount of ticks if set
 | 
				
			||||||
 | 
					} list_d;
 | 
				
			||||||
 | 
					assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(list_d));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct message_d {
 | 
					typedef struct message_d {
 | 
				
			||||||
	int msg;
 | 
						int msg;
 | 
				
			||||||
	int wparam;
 | 
						int wparam;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user