2 CLASS(XonoticServerList) EXTENDS(XonoticListBox)
3 METHOD(XonoticServerList, configureXonoticServerList, void(entity))
4 ATTRIB(XonoticServerList, rowsPerItem, float, 1)
5 METHOD(XonoticServerList, draw, void(entity))
6 METHOD(XonoticServerList, drawListBoxItem, void(entity, float, vector, float))
7 METHOD(XonoticServerList, clickListBoxItem, void(entity, float, vector))
8 METHOD(XonoticServerList, resizeNotify, void(entity, vector, vector, vector, vector))
9 METHOD(XonoticServerList, keyDown, float(entity, float, float, float))
11 ATTRIB(XonoticServerList, realFontSize, vector, '0 0 0')
12 ATTRIB(XonoticServerList, realUpperMargin, float, 0)
13 ATTRIB(XonoticServerList, columnPingOrigin, float, 0)
14 ATTRIB(XonoticServerList, columnPingSize, float, 0)
15 ATTRIB(XonoticServerList, columnNameOrigin, float, 0)
16 ATTRIB(XonoticServerList, columnNameSize, float, 0)
17 ATTRIB(XonoticServerList, columnMapOrigin, float, 0)
18 ATTRIB(XonoticServerList, columnMapSize, float, 0)
19 ATTRIB(XonoticServerList, columnTypeOrigin, float, 0)
20 ATTRIB(XonoticServerList, columnTypeSize, float, 0)
21 ATTRIB(XonoticServerList, columnPlayersOrigin, float, 0)
22 ATTRIB(XonoticServerList, columnPlayersSize, float, 0)
24 ATTRIB(XonoticServerList, selectedServer, string, string_null) // to restore selected server when needed
25 METHOD(XonoticServerList, setSelected, void(entity, float))
26 METHOD(XonoticServerList, setSortOrder, void(entity, float, float))
27 ATTRIB(XonoticServerList, filterShowEmpty, float, 1)
28 ATTRIB(XonoticServerList, filterShowFull, float, 1)
29 ATTRIB(XonoticServerList, filterString, string, string_null)
30 ATTRIB(XonoticServerList, controlledTextbox, entity, NULL)
31 ATTRIB(XonoticServerList, ipAddressBox, entity, NULL)
32 ATTRIB(XonoticServerList, favoriteButton, entity, NULL)
33 ATTRIB(XonoticServerList, nextRefreshTime, float, 0)
34 METHOD(XonoticServerList, refreshServerList, void(entity, float)) // refresh mode: 0 = just reparametrize, 1 = send new requests, 2 = clear
35 ATTRIB(XonoticServerList, needsRefresh, float, 1)
36 METHOD(XonoticServerList, focusEnter, void(entity))
37 METHOD(XonoticServerList, positionSortButton, void(entity, entity, float, float, string, void(entity, entity)))
38 ATTRIB(XonoticServerList, sortButton1, entity, NULL)
39 ATTRIB(XonoticServerList, sortButton2, entity, NULL)
40 ATTRIB(XonoticServerList, sortButton3, entity, NULL)
41 ATTRIB(XonoticServerList, sortButton4, entity, NULL)
42 ATTRIB(XonoticServerList, sortButton5, entity, NULL)
43 ATTRIB(XonoticServerList, connectButton, entity, NULL)
44 ATTRIB(XonoticServerList, infoButton, entity, NULL)
45 ATTRIB(XonoticServerList, currentSortOrder, float, 0)
46 ATTRIB(XonoticServerList, currentSortField, float, -1)
47 ATTRIB(XonoticServerList, lastClickedServer, float, -1)
48 ATTRIB(XonoticServerList, lastClickedTime, float, 0)
50 ATTRIB(XonoticServerList, ipAddressBoxFocused, float, -1)
51 ENDCLASS(XonoticServerList)
52 entity makeXonoticServerList();
53 void ServerList_Connect_Click(entity btn, entity me);
54 void ServerList_ShowEmpty_Click(entity box, entity me);
55 void ServerList_ShowFull_Click(entity box, entity me);
56 void ServerList_Filter_Change(entity box, entity me);
57 void ServerList_Favorite_Click(entity btn, entity me);
58 void ServerList_Info_Click(entity btn, entity me);
62 float SLIST_FIELD_CNAME;
63 float SLIST_FIELD_PING;
64 float SLIST_FIELD_GAME;
65 float SLIST_FIELD_MOD;
66 float SLIST_FIELD_MAP;
67 float SLIST_FIELD_NAME;
68 float SLIST_FIELD_MAXPLAYERS;
69 float SLIST_FIELD_NUMPLAYERS;
70 float SLIST_FIELD_NUMHUMANS;
71 float SLIST_FIELD_NUMBOTS;
72 float SLIST_FIELD_PROTOCOL;
73 float SLIST_FIELD_FREESLOTS;
74 float SLIST_FIELD_PLAYERS;
75 float SLIST_FIELD_QCSTATUS;
76 float SLIST_FIELD_ISFAVORITE;
77 void ServerList_UpdateFieldIDs()
79 SLIST_FIELD_CNAME = gethostcacheindexforkey( "cname" );
80 SLIST_FIELD_PING = gethostcacheindexforkey( "ping" );
81 SLIST_FIELD_GAME = gethostcacheindexforkey( "game" );
82 SLIST_FIELD_MOD = gethostcacheindexforkey( "mod" );
83 SLIST_FIELD_MAP = gethostcacheindexforkey( "map" );
84 SLIST_FIELD_NAME = gethostcacheindexforkey( "name" );
85 SLIST_FIELD_MAXPLAYERS = gethostcacheindexforkey( "maxplayers" );
86 SLIST_FIELD_NUMPLAYERS = gethostcacheindexforkey( "numplayers" );
87 SLIST_FIELD_NUMHUMANS = gethostcacheindexforkey( "numhumans" );
88 SLIST_FIELD_NUMBOTS = gethostcacheindexforkey( "numbots" );
89 SLIST_FIELD_PROTOCOL = gethostcacheindexforkey( "protocol" );
90 SLIST_FIELD_FREESLOTS = gethostcacheindexforkey( "freeslots" );
91 SLIST_FIELD_PLAYERS = gethostcacheindexforkey( "players" );
92 SLIST_FIELD_QCSTATUS = gethostcacheindexforkey( "qcstatus" );
93 SLIST_FIELD_ISFAVORITE = gethostcacheindexforkey( "isfavorite" );
96 float IsFavorite(string srv)
99 srv = netaddress_resolve(srv, 26000);
100 n = tokenize_console(cvar_string("net_slist_favorites"));
101 for(i = 0; i < n; ++i)
102 if(srv == netaddress_resolve(argv(i), 26000))
107 void ToggleFavorite(string srv)
109 string s, s0, s1, s2, srv_resolved;
111 srv_resolved = netaddress_resolve(srv, 26000);
112 s = cvar_string("net_slist_favorites");
113 n = tokenize_console(s);
114 for(i = 0; i < n; ++i)
115 if(srv_resolved == netaddress_resolve(argv(i), 26000))
119 s0 = substring(s, 0, argv_end_index(i - 1));
121 s2 = substring(s, argv_start_index(i + 1), -1);
122 if(s0 != "" && s2 != "")
124 print("s0 = >>", s0, "<<\ns1 = >>", s1, "<<\ns2 = >>", s2, "<<\n");
125 cvar_set("net_slist_favorites", strcat(s0, s1, s2));
132 cvar_set("net_slist_favorites", strcat(s, " ", srv));
137 entity makeXonoticServerList()
140 me = spawnXonoticServerList();
141 me.configureXonoticServerList(me);
144 void XonoticServerList_configureXonoticServerList(entity me)
146 me.configureXonoticListBox(me);
148 ServerList_UpdateFieldIDs();
152 void XonoticServerList_setSelected(entity me, float i)
155 save = me.selectedItem;
156 SUPER(XonoticServerList).setSelected(me, i);
158 if(me.selectedItem == save)
163 if(gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT) != me.nItems)
164 return; // sorry, it would be wrong
166 if(me.selectedServer)
167 strunzone(me.selectedServer);
168 me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem));
170 me.ipAddressBox.setText(me.ipAddressBox, me.selectedServer);
171 me.ipAddressBox.cursorPos = strlen(me.selectedServer);
172 me.ipAddressBoxFocused = -1;
174 void XonoticServerList_refreshServerList(entity me, float mode)
176 // 0: just reparametrize
177 // 1: also ask for new servers
179 //print("refresh of type ", ftos(mode), "\n");
180 /* if(mode == 2) // borken
183 localcmd("net_slist\n");
184 me.needsRefresh = 1; // net_slist kills sort order, so we need to restore it later
189 string s, typestr, modstr;
192 m = strstrofs(s, ":", 0);
195 typestr = substring(s, 0, m);
196 s = substring(s, m + 1, strlen(s) - m - 1);
197 while(substring(s, 0, 1) == " ")
198 s = substring(s, 1, strlen(s) - 1);
203 modstr = cvar_string("menu_slist_modfilter");
205 m = SLIST_MASK_AND - 1;
206 resethostcachemasks();
207 if(!me.filterShowFull)
208 sethostcachemasknumber(++m, SLIST_FIELD_FREESLOTS, 1, SLIST_TEST_GREATEREQUAL);
209 if(!me.filterShowEmpty)
210 sethostcachemasknumber(++m, SLIST_FIELD_NUMHUMANS, 1, SLIST_TEST_GREATEREQUAL);
212 sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, strcat(typestr, ":"), SLIST_TEST_STARTSWITH);
215 if(substring(modstr, 0, 1) == "!")
216 sethostcachemaskstring(++m, SLIST_FIELD_MOD, resolvemod(substring(modstr, 1, strlen(modstr) - 1)), SLIST_TEST_NOTEQUAL);
218 sethostcachemaskstring(++m, SLIST_FIELD_MOD, resolvemod(modstr), SLIST_TEST_EQUAL);
220 m = SLIST_MASK_OR - 1;
223 sethostcachemaskstring(++m, SLIST_FIELD_NAME, s, SLIST_TEST_CONTAINS);
224 sethostcachemaskstring(++m, SLIST_FIELD_MAP, s, SLIST_TEST_CONTAINS);
225 sethostcachemaskstring(++m, SLIST_FIELD_PLAYERS, s, SLIST_TEST_CONTAINS);
226 sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, strcat(s, ":"), SLIST_TEST_STARTSWITH);
228 o = 2; // favorites first
229 if(me.currentSortOrder < 0)
230 o |= 1; // descending
231 sethostcachesort(me.currentSortField, o);
237 void XonoticServerList_focusEnter(entity me)
239 if(time < me.nextRefreshTime)
241 //print("sorry, no refresh yet\n");
244 me.nextRefreshTime = time + 10;
245 me.refreshServerList(me, 1);
247 void XonoticServerList_draw(entity me)
249 float i, found, owned;
251 if(me.currentSortField == -1)
253 me.setSortOrder(me, SLIST_FIELD_PING, +1);
254 me.refreshServerList(me, 2);
256 else if(me.needsRefresh == 1)
258 me.needsRefresh = 2; // delay by one frame to make sure "slist" has been executed
260 else if(me.needsRefresh == 2)
263 me.refreshServerList(me, 0);
266 owned = ((me.selectedServer == me.ipAddressBox.text) && (me.ipAddressBox.text != ""));
268 me.nItems = gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT);
270 me.connectButton.disabled = ((me.nItems == 0) && (me.ipAddressBox.text == ""));
271 me.infoButton.disabled = ((me.nItems == 0) || !owned);
274 if(me.selectedServer)
276 for(i = 0; i < me.nItems; ++i)
277 if(gethostcachestring(SLIST_FIELD_CNAME, i) == me.selectedServer)
279 if(i != me.selectedItem)
281 me.lastClickedServer = -1;
291 if(me.selectedItem >= me.nItems)
292 me.selectedItem = me.nItems - 1;
293 if(me.selectedServer)
294 strunzone(me.selectedServer);
295 me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem));
300 if(me.selectedServer != me.ipAddressBox.text)
302 me.ipAddressBox.setText(me.ipAddressBox, me.selectedServer);
303 me.ipAddressBox.cursorPos = strlen(me.selectedServer);
304 me.ipAddressBoxFocused = -1;
308 if(me.ipAddressBoxFocused != me.ipAddressBox.focused)
310 if(me.ipAddressBox.focused || me.ipAddressBoxFocused < 0)
312 if(IsFavorite(me.ipAddressBox.text))
313 me.favoriteButton.setText(me.favoriteButton, "Remove");
315 me.favoriteButton.setText(me.favoriteButton, "Bookmark");
317 me.ipAddressBoxFocused = me.ipAddressBox.focused;
320 SUPER(XonoticServerList).draw(me);
322 void ServerList_PingSort_Click(entity btn, entity me)
324 me.setSortOrder(me, SLIST_FIELD_PING, +1);
326 void ServerList_NameSort_Click(entity btn, entity me)
328 me.setSortOrder(me, SLIST_FIELD_NAME, -1); // why?
330 void ServerList_MapSort_Click(entity btn, entity me)
332 me.setSortOrder(me, SLIST_FIELD_MAP, -1); // why?
334 void ServerList_PlayerSort_Click(entity btn, entity me)
336 me.setSortOrder(me, SLIST_FIELD_NUMHUMANS, -1);
338 void ServerList_TypeSort_Click(entity btn, entity me)
343 m = strstrofs(s, ":", 0);
346 s = substring(s, 0, m);
347 while(substring(s, m+1, 1) == " ") // skip spaces
353 for(i = 1; ; ++i) // 20 modes ought to be enough for anyone
355 t = GametypeNameFromType(i);
357 if(t == GametypeNameFromType(0)) // it repeats (default case)
360 // choose the first one
364 if(s == GametypeNameFromType(i))
366 // the type was found
367 // choose the next one
368 s = GametypeNameFromType(i + 1);
369 if(s == GametypeNameFromType(0))
377 s = strcat(s, substring(me.filterString, m+1, strlen(me.filterString) - m - 1));
379 me.controlledTextbox.setText(me.controlledTextbox, s);
380 me.controlledTextbox.keyDown(me.controlledTextbox, K_END, 0, 0);
381 me.controlledTextbox.keyUp(me.controlledTextbox, K_END, 0, 0);
382 //ServerList_Filter_Change(me.controlledTextbox, me);
384 void ServerList_Filter_Change(entity box, entity me)
387 strunzone(me.filterString);
389 me.filterString = strzone(box.text);
391 me.filterString = string_null;
392 me.refreshServerList(me, 0);
394 me.ipAddressBox.setText(me.ipAddressBox, "");
395 me.ipAddressBox.cursorPos = 0;
396 me.ipAddressBoxFocused = -1;
398 void ServerList_ShowEmpty_Click(entity box, entity me)
400 box.setChecked(box, me.filterShowEmpty = !me.filterShowEmpty);
401 me.refreshServerList(me, 0);
403 me.ipAddressBox.setText(me.ipAddressBox, "");
404 me.ipAddressBox.cursorPos = 0;
405 me.ipAddressBoxFocused = -1;
407 void ServerList_ShowFull_Click(entity box, entity me)
409 box.setChecked(box, me.filterShowFull = !me.filterShowFull);
410 me.refreshServerList(me, 0);
412 me.ipAddressBox.setText(me.ipAddressBox, "");
413 me.ipAddressBox.cursorPos = 0;
414 me.ipAddressBoxFocused = -1;
416 void XonoticServerList_setSortOrder(entity me, float field, float direction)
418 if(me.currentSortField == field)
419 direction = -me.currentSortOrder;
420 me.currentSortOrder = direction;
421 me.currentSortField = field;
422 me.sortButton1.forcePressed = (field == SLIST_FIELD_PING);
423 me.sortButton2.forcePressed = (field == SLIST_FIELD_NAME);
424 me.sortButton3.forcePressed = (field == SLIST_FIELD_MAP);
425 me.sortButton4.forcePressed = 0;
426 me.sortButton5.forcePressed = (field == SLIST_FIELD_NUMHUMANS);
428 if(me.selectedServer)
429 strunzone(me.selectedServer);
430 me.selectedServer = string_null;
431 me.refreshServerList(me, 0);
433 void XonoticServerList_positionSortButton(entity me, entity btn, float theOrigin, float theSize, string theTitle, void(entity, entity) theFunc)
435 vector originInLBSpace, sizeInLBSpace;
436 originInLBSpace = eY * (-me.itemHeight);
437 sizeInLBSpace = eY * me.itemHeight + eX * (1 - me.controlWidth);
439 vector originInDialogSpace, sizeInDialogSpace;
440 originInDialogSpace = boxToGlobal(originInLBSpace, me.Container_origin, me.Container_size);
441 sizeInDialogSpace = boxToGlobalSize(sizeInLBSpace, me.Container_size);
443 btn.Container_origin_x = originInDialogSpace_x + sizeInDialogSpace_x * theOrigin;
444 btn.Container_size_x = sizeInDialogSpace_x * theSize;
445 btn.setText(btn, theTitle);
446 btn.onClick = theFunc;
447 btn.onClickEntity = me;
450 void XonoticServerList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
452 SUPER(XonoticServerList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
454 me.realFontSize_y = me.fontSize / (absSize_y * me.itemHeight);
455 me.realFontSize_x = me.fontSize / (absSize_x * (1 - me.controlWidth));
456 me.realUpperMargin = 0.5 * (1 - me.realFontSize_y);
458 me.columnPingOrigin = 0;
459 me.columnPingSize = me.realFontSize_x * 4;
460 me.columnMapSize = me.realFontSize_x * 12;
461 me.columnTypeSize = me.realFontSize_x * 4;
462 me.columnPlayersSize = me.realFontSize_x * 6;
463 me.columnNameSize = 1 - me.columnPlayersSize - me.columnMapSize - me.columnPingSize - me.columnTypeSize - 4 * me.realFontSize_x;
464 me.columnNameOrigin = me.columnPingOrigin + me.columnPingSize + me.realFontSize_x;
465 me.columnMapOrigin = me.columnNameOrigin + me.columnNameSize + me.realFontSize_x;
466 me.columnTypeOrigin = me.columnMapOrigin + me.columnMapSize + me.realFontSize_x;
467 me.columnPlayersOrigin = me.columnTypeOrigin + me.columnTypeSize + me.realFontSize_x;
469 me.positionSortButton(me, me.sortButton1, me.columnPingOrigin, me.columnPingSize, "Ping", ServerList_PingSort_Click);
470 me.positionSortButton(me, me.sortButton2, me.columnNameOrigin, me.columnNameSize, "Host name", ServerList_NameSort_Click);
471 me.positionSortButton(me, me.sortButton3, me.columnMapOrigin, me.columnMapSize, "Map", ServerList_MapSort_Click);
472 me.positionSortButton(me, me.sortButton4, me.columnTypeOrigin, me.columnTypeSize, "Type", ServerList_TypeSort_Click);
473 me.positionSortButton(me, me.sortButton5, me.columnPlayersOrigin, me.columnPlayersSize, "Players", ServerList_PlayerSort_Click);
476 f = me.currentSortField;
479 me.currentSortField = -1;
480 me.setSortOrder(me, f, me.currentSortOrder); // force resetting the sort order
483 void ServerList_Connect_Click(entity btn, entity me)
485 if(me.ipAddressBox.text == "")
486 localcmd("connect ", me.selectedServer, "\n");
488 localcmd("connect ", me.ipAddressBox.text, "\n");
490 void ServerList_Favorite_Click(entity btn, entity me)
493 ipstr = netaddress_resolve(me.ipAddressBox.text, 26000);
496 ToggleFavorite(me.ipAddressBox.text);
497 me.ipAddressBoxFocused = -1;
500 void ServerList_Info_Click(entity btn, entity me)
502 main.serverInfoDialog.loadServerInfo(main.serverInfoDialog, me.selectedItem);
503 DialogOpenButton_Click(me, main.serverInfoDialog);
505 void XonoticServerList_clickListBoxItem(entity me, float i, vector where)
507 if(i == me.lastClickedServer)
508 if(time < me.lastClickedTime + 0.3)
511 ServerList_Connect_Click(NULL, me);
513 me.lastClickedServer = i;
514 me.lastClickedTime = time;
516 void XonoticServerList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
518 // layout: Ping, Server name, Map name, NP, TP, MP
525 draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
527 if(gethostcachenumber(SLIST_FIELD_NUMPLAYERS, i) >= gethostcachenumber(SLIST_FIELD_MAXPLAYERS, i))
528 theAlpha = SKINALPHA_SERVERLIST_FULL;
529 else if not(gethostcachenumber(SLIST_FIELD_NUMHUMANS, i))
530 theAlpha = SKINALPHA_SERVERLIST_EMPTY;
534 p = gethostcachenumber(SLIST_FIELD_PING, i);
537 #define PING_HIGH 500
539 theColor = SKINCOLOR_SERVERLIST_LOWPING + (SKINCOLOR_SERVERLIST_MEDPING - SKINCOLOR_SERVERLIST_LOWPING) * (p / PING_LOW);
540 else if(p < PING_MED)
541 theColor = SKINCOLOR_SERVERLIST_MEDPING + (SKINCOLOR_SERVERLIST_HIGHPING - SKINCOLOR_SERVERLIST_MEDPING) * ((p - PING_LOW) / (PING_MED - PING_LOW));
542 else if(p < PING_HIGH)
544 theColor = SKINCOLOR_SERVERLIST_HIGHPING;
545 theAlpha *= 1 + (SKINALPHA_SERVERLIST_HIGHPING - 1) * ((p - PING_MED) / (PING_HIGH - PING_MED));
550 theAlpha *= SKINALPHA_SERVERLIST_HIGHPING;
553 if(gethostcachenumber(SLIST_FIELD_ISFAVORITE, i))
555 theColor = theColor * (1 - SKINALPHA_SERVERLIST_FAVORITE) + SKINCOLOR_SERVERLIST_FAVORITE * SKINALPHA_SERVERLIST_FAVORITE;
556 theAlpha = theAlpha * (1 - SKINALPHA_SERVERLIST_FAVORITE) + SKINALPHA_SERVERLIST_FAVORITE;
560 draw_Text(me.realUpperMargin * eY + (me.columnPingSize - draw_TextWidth(s, 0, me.realFontSize)) * eX, s, me.realFontSize, theColor, theAlpha, 0);
561 s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_NAME, i), me.columnNameSize, 0, me.realFontSize);
562 draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, theColor, theAlpha, 0);
563 s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_MAP, i), me.columnMapSize, 0, me.realFontSize);
564 draw_Text(me.realUpperMargin * eY + (me.columnMapOrigin + (me.columnMapSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0);
565 s = gethostcachestring(SLIST_FIELD_QCSTATUS, i);
566 p = strstrofs(s, ":", 0);
568 s = substring(s, 0, p);
571 s = draw_TextShortenToWidth(s, me.columnMapSize, 0, me.realFontSize);
572 draw_Text(me.realUpperMargin * eY + (me.columnTypeOrigin + (me.columnTypeSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0);
573 s = strcat(ftos(gethostcachenumber(SLIST_FIELD_NUMHUMANS, i)), "/", ftos(gethostcachenumber(SLIST_FIELD_MAXPLAYERS, i)));
574 draw_Text(me.realUpperMargin * eY + (me.columnPlayersOrigin + (me.columnPlayersSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0);
577 float XonoticServerList_keyDown(entity me, float scan, float ascii, float shift)
582 org = boxToGlobal(eY * (me.selectedItem * me.itemHeight - me.scrollPos), me.origin, me.size);
583 sz = boxToGlobalSize(eY * me.itemHeight + eX * (1 - me.controlWidth), me.size);
587 ServerList_Connect_Click(NULL, me);
590 else if(scan == K_MOUSE2 || scan == K_SPACE)
592 main.serverInfoDialog.loadServerInfo(main.serverInfoDialog, me.selectedItem);
593 DialogOpenButton_Click_withCoords(me, main.serverInfoDialog, org, sz);
595 else if(scan == K_INS || scan == K_MOUSE3)
600 ToggleFavorite(me.selectedServer);
601 me.ipAddressBoxFocused = -1;
604 else if(SUPER(XonoticServerList).keyDown(me, scan, ascii, shift))
606 else if(!me.controlledTextbox)
609 return me.controlledTextbox.keyDown(me.controlledTextbox, scan, ascii, shift);