mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 22:48:18 +00:00
Added friends tab
This commit is contained in:
parent
625ea7d891
commit
d0f286babe
|
@ -32,6 +32,7 @@ public:
|
||||||
|
|
||||||
int NumServers() const { return m_aServerlist[m_ActServerlistType].m_NumServers; }
|
int NumServers() const { return m_aServerlist[m_ActServerlistType].m_NumServers; }
|
||||||
int NumPlayers() const { return m_aServerlist[m_ActServerlistType].m_NumPlayers; }
|
int NumPlayers() const { return m_aServerlist[m_ActServerlistType].m_NumPlayers; }
|
||||||
|
const CServerInfo *Get(int Index) const { return &m_aServerlist[m_ActServerlistType].m_ppServerlist[Index]->m_Info; };
|
||||||
|
|
||||||
int NumSortedServers(int FilterIndex) const { return m_ServerBrowserFilter.GetNumSortedServers(FilterIndex); }
|
int NumSortedServers(int FilterIndex) const { return m_ServerBrowserFilter.GetNumSortedServers(FilterIndex); }
|
||||||
int NumSortedPlayers(int FilterIndex) const { return m_ServerBrowserFilter.GetNumSortedPlayers(FilterIndex); }
|
int NumSortedPlayers(int FilterIndex) const { return m_ServerBrowserFilter.GetNumSortedPlayers(FilterIndex); }
|
||||||
|
|
|
@ -123,6 +123,7 @@ public:
|
||||||
|
|
||||||
virtual int NumServers() const = 0;
|
virtual int NumServers() const = 0;
|
||||||
virtual int NumPlayers() const = 0;
|
virtual int NumPlayers() const = 0;
|
||||||
|
virtual const CServerInfo *Get(int Index) const = 0;
|
||||||
|
|
||||||
virtual int NumSortedServers(int Index) const = 0;
|
virtual int NumSortedServers(int Index) const = 0;
|
||||||
virtual int NumSortedPlayers(int Index) const = 0;
|
virtual int NumSortedPlayers(int Index) const = 0;
|
||||||
|
|
|
@ -312,6 +312,9 @@ private:
|
||||||
int m_NumFound;
|
int m_NumFound;
|
||||||
const CFriendInfo *m_pFriendInfo;
|
const CFriendInfo *m_pFriendInfo;
|
||||||
const CServerInfo *m_pServerInfo;
|
const CServerInfo *m_pServerInfo;
|
||||||
|
char m_aName[MAX_NAME_LENGTH];
|
||||||
|
char m_aClan[MAX_CLAN_LENGTH];
|
||||||
|
bool m_IsPlayer;
|
||||||
|
|
||||||
CClanFriendItem m_ClanFriend;
|
CClanFriendItem m_ClanFriend;
|
||||||
|
|
||||||
|
@ -355,6 +358,15 @@ private:
|
||||||
int m_FriendlistSelectedIndex;
|
int m_FriendlistSelectedIndex;
|
||||||
const CFriendInfo *m_pDeleteFriendInfo;
|
const CFriendInfo *m_pDeleteFriendInfo;
|
||||||
CSelectedFriend m_SelectedFriend;
|
CSelectedFriend m_SelectedFriend;
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FRIEND_PLAYER_ON = 0,
|
||||||
|
FRIEND_CLAN_ON,
|
||||||
|
FRIEND_OFF,
|
||||||
|
NUM_FRIEND_TYPES
|
||||||
|
};
|
||||||
|
array<CFriendItem> m_lFriendList[NUM_FRIEND_TYPES];
|
||||||
|
const CFriendItem *m_pDeleteFriend;
|
||||||
|
|
||||||
bool SortCompareName(int Index1, int Index2) const;
|
bool SortCompareName(int Index1, int Index2) const;
|
||||||
bool SortCompareClan(int Index1, int Index2) const;
|
bool SortCompareClan(int Index1, int Index2) const;
|
||||||
|
|
|
@ -1379,7 +1379,210 @@ void CMenus::RenderServerbrowserSidebar(CUIRect View)
|
||||||
|
|
||||||
void CMenus::RenderServerbrowserFriendTab(CUIRect View)
|
void CMenus::RenderServerbrowserFriendTab(CUIRect View)
|
||||||
{
|
{
|
||||||
|
CUIRect Button, Icon, Label, Rect;
|
||||||
|
CUIRect BottomArea, ButtonBackground;
|
||||||
|
const float FontSize = 10.0f;
|
||||||
|
static bool s_ListExtended[NUM_FRIEND_TYPES] = { 1, 1, 0 };
|
||||||
|
static const char *s_HeaderCaption[NUM_FRIEND_TYPES] = { Localize("Online players (%d)"), Localize("Online clanmates (%d)"), Localize("Offline (%d)") };
|
||||||
|
|
||||||
|
View.HSplitBottom(3*ms_ListheaderHeight, &View, &BottomArea);
|
||||||
|
|
||||||
|
// calculate friends
|
||||||
|
// todo: optimize this
|
||||||
|
m_pDeleteFriend = 0;
|
||||||
|
m_lFriendList[0].clear();
|
||||||
|
m_lFriendList[1].clear();
|
||||||
|
m_lFriendList[2].clear();
|
||||||
|
for(int f = 0; f < m_pClient->Friends()->NumFriends(); ++f)
|
||||||
|
{
|
||||||
|
const CFriendInfo *pFriendInfo = m_pClient->Friends()->GetFriend(f);
|
||||||
|
CFriendItem FriendItem;
|
||||||
|
FriendItem.m_pServerInfo = 0;
|
||||||
|
str_copy(FriendItem.m_aName, pFriendInfo->m_aName, sizeof(FriendItem.m_aName));
|
||||||
|
str_copy(FriendItem.m_aClan, pFriendInfo->m_aClan, sizeof(FriendItem.m_aClan));
|
||||||
|
FriendItem.m_IsPlayer = false;
|
||||||
|
m_lFriendList[2].add(FriendItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int ServerIndex = 0; ServerIndex < ServerBrowser()->NumServers(); ++ServerIndex)
|
||||||
|
{
|
||||||
|
const CServerInfo *pEntry = ServerBrowser()->Get(ServerIndex);
|
||||||
|
if(pEntry->m_FriendState == IFriends::FRIEND_NO)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for(int j = 0; j < pEntry->m_NumClients; ++j)
|
||||||
|
{
|
||||||
|
if(pEntry->m_aClients[j].m_FriendState == IFriends::FRIEND_NO)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CFriendItem FriendItem;
|
||||||
|
FriendItem.m_pServerInfo = pEntry;
|
||||||
|
str_copy(FriendItem.m_aName, pEntry->m_aClients[j].m_aName, sizeof(FriendItem.m_aName));
|
||||||
|
str_copy(FriendItem.m_aClan, pEntry->m_aClients[j].m_aClan, sizeof(FriendItem.m_aClan));
|
||||||
|
FriendItem.m_IsPlayer = pEntry->m_aClients[j].m_Player;
|
||||||
|
|
||||||
|
if(pEntry->m_aClients[j].m_FriendState == IFriends::FRIEND_PLAYER)
|
||||||
|
m_lFriendList[0].add(FriendItem);
|
||||||
|
else
|
||||||
|
m_lFriendList[1].add(FriendItem);
|
||||||
|
|
||||||
|
for(int f = 0; f < m_lFriendList[2].size(); ++f)
|
||||||
|
{
|
||||||
|
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))
|
||||||
|
m_lFriendList[2].remove_index(f--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// scrollbar
|
||||||
|
UI()->ClipEnable(&View);
|
||||||
|
float Length = 0.0f;
|
||||||
|
for(int i = 0; i < NUM_FRIEND_TYPES; ++i)
|
||||||
|
{
|
||||||
|
Length += ms_ListheaderHeight + 2.0f;
|
||||||
|
if(s_ListExtended[i])
|
||||||
|
Length += (20.0f+ms_ListheaderHeight+2.0f)*m_lFriendList[i].size();
|
||||||
|
}
|
||||||
|
static float s_ScrollValue = 0.0f;
|
||||||
|
int ScrollNum = (int)((Length - View.h)/ms_ListheaderHeight)+1;
|
||||||
|
if(ScrollNum > 0)
|
||||||
|
{
|
||||||
|
if(Input()->KeyPress(KEY_MOUSE_WHEEL_UP) && UI()->MouseInside(&View))
|
||||||
|
s_ScrollValue = clamp(s_ScrollValue - 3.0f/ScrollNum, 0.0f, 1.0f);
|
||||||
|
if(Input()->KeyPress(KEY_MOUSE_WHEEL_DOWN) && UI()->MouseInside(&View))
|
||||||
|
s_ScrollValue = clamp(s_ScrollValue + 3.0f / ScrollNum, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
if(Length > View.h)
|
||||||
|
{
|
||||||
|
View.VSplitRight(8.0f, &View, &Button);
|
||||||
|
Button.HMargin(5.0f, &Button);
|
||||||
|
s_ScrollValue = DoScrollbarV(&s_ScrollValue, &Button, s_ScrollValue);
|
||||||
|
View.y += (View.h - Length) * s_ScrollValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// show lists
|
||||||
|
for(int i = 0; i < NUM_FRIEND_TYPES; ++i)
|
||||||
|
{
|
||||||
|
CUIRect Header;
|
||||||
|
char aBuf[64] = { 0 };
|
||||||
|
View.HSplitTop(ms_ListheaderHeight, &Header, &View);
|
||||||
|
if(s_ListExtended[i])
|
||||||
|
{
|
||||||
|
// entries
|
||||||
|
for(int f = 0; f < m_lFriendList[i].size(); ++f)
|
||||||
|
{
|
||||||
|
View.HSplitTop(20.0f + ms_ListheaderHeight, &Rect, &View);
|
||||||
|
RenderTools()->DrawUIRect(&Rect, vec4(0.5f, 0.5f, 0.5f, 0.5f), CUI::CORNER_ALL, 5.0f);
|
||||||
|
Rect.VMargin(2.0f, &Rect);
|
||||||
|
Rect.VSplitRight(45.0f, &Rect, &Icon);
|
||||||
|
Rect.HSplitTop(20.0f, &Button, 0);
|
||||||
|
// name
|
||||||
|
Rect.HSplitTop(10.0f, &Button, &Rect);
|
||||||
|
vec4 Colour = (i == FRIEND_PLAYER_ON) ? vec4(0.5f, 1.0f, 0.5f, 0.15f) :
|
||||||
|
(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);
|
||||||
|
RenderTools()->DrawUIRect(&Button, Colour, CUI::CORNER_T, 4.0f);
|
||||||
|
Button.VSplitLeft(2.0f, 0, &Button);
|
||||||
|
UI()->DoLabelScaled(&Button, m_lFriendList[i][f].m_aName, FontSize - 2, CUI::ALIGN_LEFT);
|
||||||
|
// clan
|
||||||
|
Rect.HSplitTop(10.0f, &Button, &Rect);
|
||||||
|
Colour = (i != FRIEND_OFF) ? vec4(0.5f, 1.0f, 0.5f, 0.15f) : vec4(1.0f, 0.5f, 0.5f, 0.15f);
|
||||||
|
RenderTools()->DrawUIRect(&Button, Colour, CUI::CORNER_B, 4.0f);
|
||||||
|
Button.VSplitLeft(2.0f, 0, &Button);
|
||||||
|
UI()->DoLabelScaled(&Button, m_lFriendList[i][f].m_aClan, FontSize - 2, CUI::ALIGN_LEFT);
|
||||||
|
// info
|
||||||
|
if(m_lFriendList[i][f].m_pServerInfo)
|
||||||
|
{
|
||||||
|
Rect.HSplitTop(ms_ListheaderHeight, &Button, &Rect);
|
||||||
|
Button.VSplitLeft(2.0f, 0, &Button);
|
||||||
|
if(m_lFriendList[i][f].m_IsPlayer)
|
||||||
|
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);
|
||||||
|
else
|
||||||
|
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);
|
||||||
|
Button.HMargin(2.0f, &Button);
|
||||||
|
UI()->DoLabelScaled(&Button, aBuf, FontSize - 2, CUI::ALIGN_LEFT);
|
||||||
|
}
|
||||||
|
// delete button
|
||||||
|
Icon.HSplitTop(20.0f, &Rect, 0);
|
||||||
|
Rect.VSplitRight(10.0f, &Button, &Icon);
|
||||||
|
Icon.HMargin((Icon.h - Icon.w) / 2, &Icon);
|
||||||
|
if(DoButton_SpriteClean(IMAGE_TOOLICONS, SPRITE_TOOL_X_B, &Icon))
|
||||||
|
{
|
||||||
|
m_pDeleteFriend = &m_lFriendList[i][f];
|
||||||
|
}
|
||||||
|
// join button
|
||||||
|
if(m_lFriendList[i][f].m_pServerInfo)
|
||||||
|
{
|
||||||
|
Button.Margin((Button.h - ms_ListheaderHeight + 2.0f) / 2, &Button);
|
||||||
|
RenderTools()->DrawUIRect(&Button, vec4(1.0f, 1.0f, 1.0f, 0.15f), CUI::CORNER_ALL, 4.0f);
|
||||||
|
Label.HMargin(2.0f, &Label);
|
||||||
|
UI()->DoLabelScaled(&Button, Localize("Join"), FontSize, CUI::ALIGN_CENTER);
|
||||||
|
if(UI()->MouseInside(&Button) && Input()->KeyPress(KEY_MOUSE_1)) // todo: fix me
|
||||||
|
{
|
||||||
|
str_copy(g_Config.m_UiServerAddress, m_lFriendList[i][f].m_pServerInfo->m_aAddress, sizeof(g_Config.m_UiServerAddress));
|
||||||
|
Client()->Connect(g_Config.m_UiServerAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(f < m_lFriendList[i].size()-1)
|
||||||
|
View.HSplitTop(2.0f, 0, &View);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
View.HSplitTop(2.0f, 0, &View);
|
||||||
|
|
||||||
|
// header
|
||||||
|
RenderTools()->DrawUIRect(&Header, vec4(0.0f, 0.0f, 0.0f, 0.25f), CUI::CORNER_ALL, 5.0f);
|
||||||
|
Header.VSplitLeft(Header.h, &Icon, &Label);
|
||||||
|
DoIcon(IMAGE_MENUICONS, s_ListExtended[i] ? SPRITE_MENU_EXPANDED : SPRITE_MENU_COLLAPSED, &Icon);
|
||||||
|
str_format(aBuf, sizeof(aBuf), s_HeaderCaption[i], m_lFriendList[i].size());
|
||||||
|
Label.HMargin(2.0f, &Label);
|
||||||
|
UI()->DoLabelScaled(&Label, aBuf, FontSize, CUI::ALIGN_LEFT);
|
||||||
|
static int s_HeaderButton[NUM_FRIEND_TYPES] = { 0 };
|
||||||
|
if(UI()->DoButtonLogic(&s_HeaderButton[i], "", 0, &Header))
|
||||||
|
{
|
||||||
|
s_ListExtended[i] ^= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UI()->ClipDisable();
|
||||||
|
|
||||||
|
// add friend
|
||||||
|
BottomArea.HSplitTop(ms_ListheaderHeight, &Button, &BottomArea);
|
||||||
|
Button.VSplitLeft(50.0f, &Label, &Button);
|
||||||
|
UI()->DoLabelScaled(&Label, Localize("Name"), FontSize, CUI::ALIGN_LEFT);
|
||||||
|
static char s_aName[MAX_NAME_LENGTH] = { 0 };
|
||||||
|
static float s_OffsetName = 0.0f;
|
||||||
|
DoEditBox(&s_aName, &Button, s_aName, sizeof(s_aName), Button.h*ms_FontmodHeight*0.8f, &s_OffsetName);
|
||||||
|
|
||||||
|
BottomArea.HSplitTop(ms_ListheaderHeight, &Button, &BottomArea);
|
||||||
|
Button.VSplitLeft(50.0f, &Label, &Button);
|
||||||
|
UI()->DoLabelScaled(&Label, Localize("Clan"), FontSize, CUI::ALIGN_LEFT);
|
||||||
|
static char s_aClan[MAX_CLAN_LENGTH] = { 0 };
|
||||||
|
static float s_OffsetClan = 0.0f;
|
||||||
|
DoEditBox(&s_aClan, &Button, s_aClan, sizeof(s_aClan), Button.h*ms_FontmodHeight*0.8f, &s_OffsetClan);
|
||||||
|
|
||||||
|
BottomArea.HSplitTop(ms_ListheaderHeight, &Button, &BottomArea);
|
||||||
|
RenderTools()->DrawUIRect(&Button, vec4(1.0f, 1.0f, 1.0f, 0.25f), CUI::CORNER_ALL, 5.0f);
|
||||||
|
Button.VSplitLeft(Button.h, &Icon, &Label);
|
||||||
|
Label.HMargin(2.0f, &Label);
|
||||||
|
UI()->DoLabelScaled(&Label, Localize("Add friend"), FontSize, CUI::ALIGN_CENTER);
|
||||||
|
if(s_aName[0] || s_aClan[0])
|
||||||
|
DoIcon(IMAGE_FRIENDICONS, UI()->MouseInside(&Button)?SPRITE_FRIEND_PLUS_A:SPRITE_FRIEND_PLUS_B, &Icon);
|
||||||
|
static CButtonContainer s_AddFriend;
|
||||||
|
if((s_aName[0] || s_aClan[0]) && UI()->DoButtonLogic(&s_AddFriend, "", 0, &Button))
|
||||||
|
{
|
||||||
|
m_pClient->Friends()->AddFriend(s_aName, s_aClan);
|
||||||
|
FriendlistOnUpdate();
|
||||||
|
Client()->ServerBrowserUpdate();
|
||||||
|
s_aName[0] = 0;
|
||||||
|
s_aClan[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete friend
|
||||||
|
if(m_pDeleteFriend)
|
||||||
|
{
|
||||||
|
m_pClient->Friends()->RemoveFriend(m_pDeleteFriend->m_aName, m_pDeleteFriend->m_aClan);
|
||||||
|
FriendlistOnUpdate();
|
||||||
|
Client()->ServerBrowserUpdate();
|
||||||
|
m_pDeleteFriend = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMenus::RenderServerbrowserFilterTab(CUIRect View)
|
void CMenus::RenderServerbrowserFilterTab(CUIRect View)
|
||||||
|
|
Loading…
Reference in a new issue