@@ -1379,7 +1379,210 @@ void CMenus::RenderServerbrowserSidebar(CUIRect View)
1379
1379
1380
1380
void CMenus::RenderServerbrowserFriendTab (CUIRect View)
1381
1381
{
1382
+ CUIRect Button, Icon, Label, Rect;
1383
+ CUIRect BottomArea, ButtonBackground;
1384
+ const float FontSize = 10 .0f ;
1385
+ static bool s_ListExtended[NUM_FRIEND_TYPES] = { 1 , 1 , 0 };
1386
+ static const char *s_HeaderCaption[NUM_FRIEND_TYPES] = { Localize (" Online players (%d)" ), Localize (" Online clanmates (%d)" ), Localize (" Offline (%d)" ) };
1387
+
1388
+ View.HSplitBottom (3 *ms_ListheaderHeight, &View, &BottomArea);
1389
+
1390
+ // calculate friends
1391
+ // todo: optimize this
1392
+ m_pDeleteFriend = 0 ;
1393
+ m_lFriendList[0 ].clear ();
1394
+ m_lFriendList[1 ].clear ();
1395
+ m_lFriendList[2 ].clear ();
1396
+ for (int f = 0 ; f < m_pClient->Friends ()->NumFriends (); ++f)
1397
+ {
1398
+ const CFriendInfo *pFriendInfo = m_pClient->Friends ()->GetFriend (f);
1399
+ CFriendItem FriendItem;
1400
+ FriendItem.m_pServerInfo = 0 ;
1401
+ str_copy (FriendItem.m_aName , pFriendInfo->m_aName , sizeof (FriendItem.m_aName ));
1402
+ str_copy (FriendItem.m_aClan , pFriendInfo->m_aClan , sizeof (FriendItem.m_aClan ));
1403
+ FriendItem.m_IsPlayer = false ;
1404
+ m_lFriendList[2 ].add (FriendItem);
1405
+ }
1406
+
1407
+ for (int ServerIndex = 0 ; ServerIndex < ServerBrowser ()->NumServers (); ++ServerIndex)
1408
+ {
1409
+ const CServerInfo *pEntry = ServerBrowser ()->Get (ServerIndex);
1410
+ if (pEntry->m_FriendState == IFriends::FRIEND_NO)
1411
+ continue ;
1412
+
1413
+ for (int j = 0 ; j < pEntry->m_NumClients ; ++j)
1414
+ {
1415
+ if (pEntry->m_aClients [j].m_FriendState == IFriends::FRIEND_NO)
1416
+ continue ;
1417
+
1418
+ CFriendItem FriendItem;
1419
+ FriendItem.m_pServerInfo = pEntry;
1420
+ str_copy (FriendItem.m_aName , pEntry->m_aClients [j].m_aName , sizeof (FriendItem.m_aName ));
1421
+ str_copy (FriendItem.m_aClan , pEntry->m_aClients [j].m_aClan , sizeof (FriendItem.m_aClan ));
1422
+ FriendItem.m_IsPlayer = pEntry->m_aClients [j].m_Player ;
1423
+
1424
+ if (pEntry->m_aClients [j].m_FriendState == IFriends::FRIEND_PLAYER)
1425
+ m_lFriendList[0 ].add (FriendItem);
1426
+ else
1427
+ m_lFriendList[1 ].add (FriendItem);
1428
+
1429
+ for (int f = 0 ; f < m_lFriendList[2 ].size (); ++f)
1430
+ {
1431
+ if ((!m_lFriendList[2 ][f].m_aName [0 ] || !str_comp (m_lFriendList[2 ][f].m_aName , pEntry->m_aClients [j].m_aName )) && !str_comp (m_lFriendList[2 ][f].m_aClan , pEntry->m_aClients [j].m_aClan ))
1432
+ m_lFriendList[2 ].remove_index (f--);
1433
+ }
1434
+ }
1435
+ }
1436
+
1437
+ // scrollbar
1438
+ UI ()->ClipEnable (&View);
1439
+ float Length = 0 .0f ;
1440
+ for (int i = 0 ; i < NUM_FRIEND_TYPES; ++i)
1441
+ {
1442
+ Length += ms_ListheaderHeight + 2 .0f ;
1443
+ if (s_ListExtended[i])
1444
+ Length += (20 .0f +ms_ListheaderHeight+2 .0f )*m_lFriendList[i].size ();
1445
+ }
1446
+ static float s_ScrollValue = 0 .0f ;
1447
+ int ScrollNum = (int )((Length - View.h )/ms_ListheaderHeight)+1 ;
1448
+ if (ScrollNum > 0 )
1449
+ {
1450
+ if (Input ()->KeyPress (KEY_MOUSE_WHEEL_UP) && UI ()->MouseInside (&View))
1451
+ s_ScrollValue = clamp (s_ScrollValue - 3 .0f /ScrollNum, 0 .0f , 1 .0f );
1452
+ if (Input ()->KeyPress (KEY_MOUSE_WHEEL_DOWN) && UI ()->MouseInside (&View))
1453
+ s_ScrollValue = clamp (s_ScrollValue + 3 .0f / ScrollNum, 0 .0f , 1 .0f );
1454
+ }
1455
+ if (Length > View.h )
1456
+ {
1457
+ View.VSplitRight (8 .0f , &View, &Button);
1458
+ Button.HMargin (5 .0f , &Button);
1459
+ s_ScrollValue = DoScrollbarV (&s_ScrollValue, &Button, s_ScrollValue);
1460
+ View.y += (View.h - Length) * s_ScrollValue;
1461
+ }
1462
+
1463
+ // show lists
1464
+ for (int i = 0 ; i < NUM_FRIEND_TYPES; ++i)
1465
+ {
1466
+ CUIRect Header;
1467
+ char aBuf[64 ] = { 0 };
1468
+ View.HSplitTop (ms_ListheaderHeight, &Header, &View);
1469
+ if (s_ListExtended[i])
1470
+ {
1471
+ // entries
1472
+ for (int f = 0 ; f < m_lFriendList[i].size (); ++f)
1473
+ {
1474
+ View.HSplitTop (20 .0f + ms_ListheaderHeight, &Rect, &View);
1475
+ RenderTools ()->DrawUIRect (&Rect, vec4 (0 .5f , 0 .5f , 0 .5f , 0 .5f ), CUI::CORNER_ALL, 5 .0f );
1476
+ Rect.VMargin (2 .0f , &Rect);
1477
+ Rect.VSplitRight (45 .0f , &Rect, &Icon);
1478
+ Rect.HSplitTop (20 .0f , &Button, 0 );
1479
+ // name
1480
+ Rect.HSplitTop (10 .0f , &Button, &Rect);
1481
+ vec4 Colour = (i == FRIEND_PLAYER_ON) ? vec4 (0 .5f , 1 .0f , 0 .5f , 0 .15f ) :
1482
+ (i == FRIEND_CLAN_ON || !m_lFriendList[i][f].m_aName [0 ]) ? vec4 (0 .0f , 0 .0f , 0 .0f , 0 .15f ) : vec4 (1 .0f , 0 .5f , 0 .5f , 0 .15f );
1483
+ RenderTools ()->DrawUIRect (&Button, Colour, CUI::CORNER_T, 4 .0f );
1484
+ Button.VSplitLeft (2 .0f , 0 , &Button);
1485
+ UI ()->DoLabelScaled (&Button, m_lFriendList[i][f].m_aName , FontSize - 2 , CUI::ALIGN_LEFT);
1486
+ // clan
1487
+ Rect.HSplitTop (10 .0f , &Button, &Rect);
1488
+ Colour = (i != FRIEND_OFF) ? vec4 (0 .5f , 1 .0f , 0 .5f , 0 .15f ) : vec4 (1 .0f , 0 .5f , 0 .5f , 0 .15f );
1489
+ RenderTools ()->DrawUIRect (&Button, Colour, CUI::CORNER_B, 4 .0f );
1490
+ Button.VSplitLeft (2 .0f , 0 , &Button);
1491
+ UI ()->DoLabelScaled (&Button, m_lFriendList[i][f].m_aClan , FontSize - 2 , CUI::ALIGN_LEFT);
1492
+ // info
1493
+ if (m_lFriendList[i][f].m_pServerInfo )
1494
+ {
1495
+ Rect.HSplitTop (ms_ListheaderHeight, &Button, &Rect);
1496
+ Button.VSplitLeft (2 .0f , 0 , &Button);
1497
+ if (m_lFriendList[i][f].m_IsPlayer )
1498
+ str_format (aBuf, sizeof (aBuf), Localize (" Playing '%s' on '%s'" ), m_lFriendList[i][f].m_pServerInfo ->m_aGameType , m_lFriendList[i][f].m_pServerInfo ->m_aMap );
1499
+ else
1500
+ str_format (aBuf, sizeof (aBuf), Localize (" Watching '%s' on '%s'" ), m_lFriendList[i][f].m_pServerInfo ->m_aGameType , m_lFriendList[i][f].m_pServerInfo ->m_aMap );
1501
+ Button.HMargin (2 .0f , &Button);
1502
+ UI ()->DoLabelScaled (&Button, aBuf, FontSize - 2 , CUI::ALIGN_LEFT);
1503
+ }
1504
+ // delete button
1505
+ Icon.HSplitTop (20 .0f , &Rect, 0 );
1506
+ Rect.VSplitRight (10 .0f , &Button, &Icon);
1507
+ Icon.HMargin ((Icon.h - Icon.w ) / 2 , &Icon);
1508
+ if (DoButton_SpriteClean (IMAGE_TOOLICONS, SPRITE_TOOL_X_B, &Icon))
1509
+ {
1510
+ m_pDeleteFriend = &m_lFriendList[i][f];
1511
+ }
1512
+ // join button
1513
+ if (m_lFriendList[i][f].m_pServerInfo )
1514
+ {
1515
+ Button.Margin ((Button.h - ms_ListheaderHeight + 2 .0f ) / 2 , &Button);
1516
+ RenderTools ()->DrawUIRect (&Button, vec4 (1 .0f , 1 .0f , 1 .0f , 0 .15f ), CUI::CORNER_ALL, 4 .0f );
1517
+ Label.HMargin (2 .0f , &Label);
1518
+ UI ()->DoLabelScaled (&Button, Localize (" Join" ), FontSize, CUI::ALIGN_CENTER);
1519
+ if (UI ()->MouseInside (&Button) && Input ()->KeyPress (KEY_MOUSE_1)) // todo: fix me
1520
+ {
1521
+ str_copy (g_Config.m_UiServerAddress , m_lFriendList[i][f].m_pServerInfo ->m_aAddress , sizeof (g_Config.m_UiServerAddress ));
1522
+ Client ()->Connect (g_Config.m_UiServerAddress );
1523
+ }
1524
+ }
1525
+ if (f < m_lFriendList[i].size ()-1 )
1526
+ View.HSplitTop (2 .0f , 0 , &View);
1527
+ }
1528
+ }
1529
+ View.HSplitTop (2 .0f , 0 , &View);
1530
+
1531
+ // header
1532
+ RenderTools ()->DrawUIRect (&Header, vec4 (0 .0f , 0 .0f , 0 .0f , 0 .25f ), CUI::CORNER_ALL, 5 .0f );
1533
+ Header.VSplitLeft (Header.h , &Icon, &Label);
1534
+ DoIcon (IMAGE_MENUICONS, s_ListExtended[i] ? SPRITE_MENU_EXPANDED : SPRITE_MENU_COLLAPSED, &Icon);
1535
+ str_format (aBuf, sizeof (aBuf), s_HeaderCaption[i], m_lFriendList[i].size ());
1536
+ Label.HMargin (2 .0f , &Label);
1537
+ UI ()->DoLabelScaled (&Label, aBuf, FontSize, CUI::ALIGN_LEFT);
1538
+ static int s_HeaderButton[NUM_FRIEND_TYPES] = { 0 };
1539
+ if (UI ()->DoButtonLogic (&s_HeaderButton[i], " " , 0 , &Header))
1540
+ {
1541
+ s_ListExtended[i] ^= 1 ;
1542
+ }
1543
+ }
1544
+ UI ()->ClipDisable ();
1382
1545
1546
+ // add friend
1547
+ BottomArea.HSplitTop (ms_ListheaderHeight, &Button, &BottomArea);
1548
+ Button.VSplitLeft (50 .0f , &Label, &Button);
1549
+ UI ()->DoLabelScaled (&Label, Localize (" Name" ), FontSize, CUI::ALIGN_LEFT);
1550
+ static char s_aName[MAX_NAME_LENGTH] = { 0 };
1551
+ static float s_OffsetName = 0 .0f ;
1552
+ DoEditBox (&s_aName, &Button, s_aName, sizeof (s_aName), Button.h *ms_FontmodHeight*0 .8f , &s_OffsetName);
1553
+
1554
+ BottomArea.HSplitTop (ms_ListheaderHeight, &Button, &BottomArea);
1555
+ Button.VSplitLeft (50 .0f , &Label, &Button);
1556
+ UI ()->DoLabelScaled (&Label, Localize (" Clan" ), FontSize, CUI::ALIGN_LEFT);
1557
+ static char s_aClan[MAX_CLAN_LENGTH] = { 0 };
1558
+ static float s_OffsetClan = 0 .0f ;
1559
+ DoEditBox (&s_aClan, &Button, s_aClan, sizeof (s_aClan), Button.h *ms_FontmodHeight*0 .8f , &s_OffsetClan);
1560
+
1561
+ BottomArea.HSplitTop (ms_ListheaderHeight, &Button, &BottomArea);
1562
+ RenderTools ()->DrawUIRect (&Button, vec4 (1 .0f , 1 .0f , 1 .0f , 0 .25f ), CUI::CORNER_ALL, 5 .0f );
1563
+ Button.VSplitLeft (Button.h , &Icon, &Label);
1564
+ Label.HMargin (2 .0f , &Label);
1565
+ UI ()->DoLabelScaled (&Label, Localize (" Add friend" ), FontSize, CUI::ALIGN_CENTER);
1566
+ if (s_aName[0 ] || s_aClan[0 ])
1567
+ DoIcon (IMAGE_FRIENDICONS, UI ()->MouseInside (&Button)?SPRITE_FRIEND_PLUS_A:SPRITE_FRIEND_PLUS_B, &Icon);
1568
+ static CButtonContainer s_AddFriend;
1569
+ if ((s_aName[0 ] || s_aClan[0 ]) && UI ()->DoButtonLogic (&s_AddFriend, " " , 0 , &Button))
1570
+ {
1571
+ m_pClient->Friends ()->AddFriend (s_aName, s_aClan);
1572
+ FriendlistOnUpdate ();
1573
+ Client ()->ServerBrowserUpdate ();
1574
+ s_aName[0 ] = 0 ;
1575
+ s_aClan[0 ] = 0 ;
1576
+ }
1577
+
1578
+ // delete friend
1579
+ if (m_pDeleteFriend)
1580
+ {
1581
+ m_pClient->Friends ()->RemoveFriend (m_pDeleteFriend->m_aName , m_pDeleteFriend->m_aClan );
1582
+ FriendlistOnUpdate ();
1583
+ Client ()->ServerBrowserUpdate ();
1584
+ m_pDeleteFriend = 0 ;
1585
+ }
1383
1586
}
1384
1587
1385
1588
void CMenus::RenderServerbrowserFilterTab (CUIRect View)
0 commit comments