-integrated popups into menu -made filter editable

This commit is contained in:
SushiTee 2012-01-15 01:05:08 +01:00 committed by oy
parent 1220bafb0e
commit 4b57161752
7 changed files with 306 additions and 9 deletions

View file

@ -73,6 +73,28 @@ int CServerBrowser::AddFilter(int SortHash, int Ping, int Country, const char* p
return m_lFilters.size()-1;
}
void CServerBrowser::GetFilter(int Index, int *pSortHash, int *pPing, int *pCountry, char* pGametype, char* pServerAddress)
{
CServerFilter *pFilter = &m_lFilters[Index];
*pSortHash = pFilter->m_SortHash;
*pPing = pFilter->m_Ping;
*pCountry = pFilter->m_Country;
str_copy(pGametype, pFilter->m_aGametype, sizeof(pFilter->m_aGametype));
str_copy(pServerAddress, pFilter->m_aServerAddress, sizeof(pFilter->m_aServerAddress));
}
void CServerBrowser::SetFilter(int Index, int SortHash, int Ping, int Country, const char* pGametype, const char* pServerAddress)
{
CServerFilter *pFilter = &m_lFilters[Index];
pFilter->m_SortHash = SortHash;
pFilter->m_Ping = Ping;
pFilter->m_Country = Country;
str_copy(pFilter->m_aGametype, pGametype, sizeof(pFilter->m_aGametype));
str_copy(pFilter->m_aServerAddress, pServerAddress, sizeof(pFilter->m_aServerAddress));
pFilter->m_pServerBrowser->Update(true);
}
void CServerBrowser::RemoveFilter(int Index)
{
m_lFilters.remove_index(Index);

View file

@ -64,6 +64,8 @@ public:
array<CServerFilter> m_lFilters;
int AddFilter(int SortHash, int Ping, int Country, const char* pGametype, const char* pServerAddress);
void SetFilter(int Index, int SortHash, int Ping, int Country, const char* pGametype, const char* pServerAddress);
void GetFilter(int Index, int *pSortHash, int *pPing, int *pCountry, char* pGametype, char* pServerAddress);
void RemoveFilter(int Index);
CServerBrowser();

View file

@ -117,6 +117,8 @@ public:
virtual void RemoveFavorite(const NETADDR &Addr) = 0;
virtual int AddFilter(int Flag, int Ping, int Country, const char* pGametype, const char* pServerAddress) = 0;
virtual void SetFilter(int Index, int SortHash, int Ping, int Country, const char* pGametype, const char* pServerAddress) = 0;
virtual void GetFilter(int Index, int *pSortHash, int *pPing, int *pCountry, char* pGametype, char* pServerAddress) = 0;
virtual void RemoveFilter(int Index) = 0;
};

View file

@ -74,6 +74,8 @@ CMenus::CMenus()
m_FriendlistSelectedIndex = -1;
m_SelectedFilter = 0;
m_SelectedServer.m_Filter = -1;
m_SelectedServer.m_Index = -1;
}
@ -301,6 +303,21 @@ int CMenus::DoButton_SpriteClean(int ImageID, int SpriteID, const CUIRect *pRect
return ReturnValue;
}
int CMenus::DoButton_SpriteCleanID(const void *pID, int ImageID, int SpriteID, const CUIRect *pRect)
{
int Inside = UI()->MouseInside(pRect);
Graphics()->TextureSet(g_pData->m_aImages[ImageID].m_Id);
Graphics()->QuadsBegin();
Graphics()->SetColor(1.0f, 1.0f, 1.0f, Inside ? 1.0f : 0.6f);
RenderTools()->SelectSprite(SpriteID);
IGraphics::CQuadItem QuadItem(pRect->x, pRect->y, pRect->w, pRect->h);
Graphics()->QuadsDrawTL(&QuadItem, 1);
Graphics()->QuadsEnd();
return UI()->DoButtonLogic(pID, 0, 0, pRect);
}
int CMenus::DoButton_MouseOver(int ImageID, int SpriteID, const CUIRect *pRect)
{
int Inside = UI()->MouseInside(pRect);
@ -1184,6 +1201,9 @@ int CMenus::Render()
m_MenuPage = PAGE_START;
}
}
// do overlay popups
DoPopupMenu();
}
else
{
@ -1451,9 +1471,18 @@ int CMenus::Render()
Box.HSplitBottom(20.f, &Box, 0);
Box.VMargin(20.0f, &Box);
// selected filter
CBrowserFilter *pFilter = &m_lFilters[m_SelectedFilter];
int SortHash = 0;
int Ping = 0;
int Country = 0;
char aGametype[32];
char aServerAddress[16];
pFilter->GetFilter(&SortHash, &Ping, &Country, aGametype, aServerAddress);
static int ActSelection = -2;
if(ActSelection == -2)
ActSelection = g_Config.m_BrFilterCountryIndex;
ActSelection = Country;
static float s_ScrollValue = 0.0f;
int OldSelected = -1;
UiDoListboxStart(&s_ScrollValue, &Box, 50.0f, Localize("Country"), "", m_pClient->m_pCountryFlags->Num(), 6, OldSelected, s_ScrollValue);
@ -1488,14 +1517,13 @@ int CMenus::Render()
static int s_Button = 0;
if(DoButton_Menu(&s_Button, Localize("Ok"), 0, &Part) || m_EnterPressed)
{
g_Config.m_BrFilterCountryIndex = ActSelection;
Client()->ServerBrowserUpdate();
pFilter->SetFilter(SortHash, Ping, ActSelection, aGametype, aServerAddress);
m_Popup = POPUP_NONE;
}
if(m_EscapePressed)
{
ActSelection = g_Config.m_BrFilterCountryIndex;
ActSelection = Country;
m_Popup = POPUP_NONE;
}
}

View file

@ -42,6 +42,7 @@ class CMenus : public CComponent
int DoButton_DemoPlayer(const void *pID, const char *pText, const CUIRect *pRect);
int DoButton_Sprite(const void *pID, int ImageID, int SpriteID, const CUIRect *pRect, int Corners);
int DoButton_SpriteClean(int ImageID, int SpriteID, const CUIRect *pRect);
int DoButton_SpriteCleanID(const void *pID, int ImageID, int SpriteID, const CUIRect *pRect);
int DoButton_Toggle(const void *pID, int Checked, const CUIRect *pRect, bool Active);
int DoButton_Menu(const void *pID, const char *pText, int Checked, const CUIRect *pRect, float r=5.0f, float FontFactor=0.0f, int Corners=CUI::CORNER_ALL);
int DoButton_MenuImage(const void *pID, const char *pText, int Checked, const CUIRect *pRect, const char *pImageName, float r=5.0f, float FontFactor=0.0f);
@ -287,16 +288,21 @@ class CMenus : public CComponent
int Filter() const;
const char* Name() const;
void SetFilter(int Num);
void SetFilterNum(int Num);
int NumSortedServers() const;
int NumPlayers() const;
const CServerInfo *SortedGet(int Index) const;
const void *ID(int Index) const;
void GetFilter(int *pSortHash, int *pPing, int *pCountry, char* pGametype, char* pServerAddress);
void SetFilter(int SortHash, int Ping, int Country, const char* pGametype, const char* pServerAddress);
};
array<CBrowserFilter> m_lFilters;
int m_SelectedFilter;
void RemoveFilter(int FilterIndex);
void Move(bool Up, int Filter);
@ -406,6 +412,12 @@ class CMenus : public CComponent
void RenderSettings(CUIRect MainView);
void SetActive(bool Active);
void InvokePopupMenu(void *pID, int Flags, float X, float Y, float W, float H, int (*pfnFunc)(CMenus *pMenu, CUIRect Rect), void *pExtra=0);
void DoPopupMenu();
static int PopupFilter(CMenus *pMenus, CUIRect View);
public:
void RenderBackground();

View file

@ -88,11 +88,21 @@ const CServerInfo *CMenus::CBrowserFilter::SortedGet(int Index) const
return m_pServerBrowser->SortedGet(m_Filter, Index);
}
void CMenus::CBrowserFilter::SetFilter(int Num)
void CMenus::CBrowserFilter::SetFilterNum(int Num)
{
m_Filter = Num;
}
void CMenus::CBrowserFilter::GetFilter(int *pSortHash, int *pPing, int *pCountry, char* pGametype, char* pServerAddress)
{
m_pServerBrowser->GetFilter(m_Filter, pSortHash, pPing, pCountry, pGametype, pServerAddress);
}
void CMenus::CBrowserFilter::SetFilter(int SortHash, int Ping, int Country, const char* pGametype, const char* pServerAddress)
{
m_pServerBrowser->SetFilter(m_Filter, SortHash, Ping, Country, pGametype, pServerAddress);
}
void CMenus::RemoveFilter(int FilterIndex)
{
int Filter = m_lFilters[FilterIndex].Filter();
@ -104,7 +114,7 @@ void CMenus::RemoveFilter(int FilterIndex)
{
CBrowserFilter *pFilter = &m_lFilters[i];
if(pFilter->Filter() > Filter)
pFilter->SetFilter(pFilter->Filter()-1);
pFilter->SetFilterNum(pFilter->Filter()-1);
}
}
@ -402,9 +412,11 @@ bool CMenus::RenderFilterHeader(CUIRect View, int FilterIndex)
View.VSplitRight(2.0f, &Button, 0);
Button.VSplitRight(18.0f, &View, &Button);
if(DoButton_SpriteClean(IMAGE_BROWSERICONS, SPRITE_BROWSERICON_EDIT, &Button))
if(DoButton_SpriteCleanID(pFilter, IMAGE_BROWSERICONS, SPRITE_BROWSERICON_EDIT, &Button)) // TODO: using the address of filter as ID is prolly a bad idea
{
//
static int s_EditPopupID = 0;
m_SelectedFilter = FilterIndex;
InvokePopupMenu(&s_EditPopupID, 0, UI()->MouseX(), UI()->MouseY(), 200.0f, 310.0f, PopupFilter);
}
View.VSplitRight(2.0f, &Button, 0);

View file

@ -0,0 +1,219 @@
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
#include <base/tl/array.h>
#include <engine/shared/config.h>
#include <engine/console.h>
#include <engine/graphics.h>
#include <engine/input.h>
#include <engine/keys.h>
#include <engine/storage.h>
#include <engine/serverbrowser.h>
#include "countryflags.h"
#include "menus.h"
// popup menu handling
static struct
{
CUIRect m_Rect;
void *m_pId;
int (*m_pfnFunc)(CMenus *pMenu, CUIRect Rect);
int m_IsMenu;
void *m_pExtra;
} s_Popups[8];
static int g_NumPopups = 0;
void CMenus::InvokePopupMenu(void *pID, int Flags, float x, float y, float Width, float Height, int (*pfnFunc)(CMenus *pMenu, CUIRect Rect), void *pExtra)
{
if(x + Width > UI()->Screen()->w)
x -= Width;
if(y + Height > UI()->Screen()->h)
y -= Height;
s_Popups[g_NumPopups].m_pId = pID;
s_Popups[g_NumPopups].m_IsMenu = Flags;
s_Popups[g_NumPopups].m_Rect.x = x;
s_Popups[g_NumPopups].m_Rect.y = y;
s_Popups[g_NumPopups].m_Rect.w = Width;
s_Popups[g_NumPopups].m_Rect.h = Height;
s_Popups[g_NumPopups].m_pfnFunc = pfnFunc;
s_Popups[g_NumPopups].m_pExtra = pExtra;
g_NumPopups++;
}
void CMenus::DoPopupMenu()
{
for(int i = 0; i < g_NumPopups; i++)
{
bool Inside = UI()->MouseInside(&s_Popups[i].m_Rect);
UI()->SetHotItem(&s_Popups[i].m_pId);
if(UI()->ActiveItem() == &s_Popups[i].m_pId)
{
if(!UI()->MouseButton(0))
{
if(!Inside)
g_NumPopups--;
UI()->SetActiveItem(0);
}
}
else if(UI()->HotItem() == &s_Popups[i].m_pId)
{
if(UI()->MouseButton(0))
UI()->SetActiveItem(&s_Popups[i].m_pId);
}
int Corners = CUI::CORNER_ALL;
if(s_Popups[i].m_IsMenu)
Corners = CUI::CORNER_R|CUI::CORNER_B;
CUIRect r = s_Popups[i].m_Rect;
RenderTools()->DrawUIRect(&r, vec4(0.5f,0.5f,0.5f,0.75f), Corners, 3.0f);
r.Margin(1.0f, &r);
RenderTools()->DrawUIRect(&r, vec4(0,0,0,0.75f), Corners, 3.0f);
r.Margin(4.0f, &r);
if(s_Popups[i].m_pfnFunc(this, r))
g_NumPopups--;
if(Input()->KeyDown(KEY_ESCAPE))
g_NumPopups--;
}
}
int CMenus::PopupFilter(CMenus *pMenus, CUIRect View)
{
CUIRect ServerFilter = View, FilterHeader;
const float FontSize = 12.0f;
// slected filter
CBrowserFilter *pFilter = &pMenus->m_lFilters[pMenus->m_SelectedFilter];
int SortHash = 0;
int Ping = 0;
int Country = 0;
char aGametype[32];
char aServerAddress[16];
pFilter->GetFilter(&SortHash, &Ping, &Country, aGametype, aServerAddress);
// server filter
ServerFilter.HSplitTop(ms_ListheaderHeight, &FilterHeader, &ServerFilter);
pMenus->RenderTools()->DrawUIRect(&FilterHeader, vec4(1,1,1,0.25f), CUI::CORNER_T, 4.0f);
pMenus->RenderTools()->DrawUIRect(&ServerFilter, vec4(0,0,0,0.15f), CUI::CORNER_B, 4.0f);
pMenus->UI()->DoLabelScaled(&FilterHeader, Localize("Server filter"), FontSize+2.0f, 0);
CUIRect Button;
ServerFilter.VSplitLeft(5.0f, 0, &ServerFilter);
ServerFilter.Margin(3.0f, &ServerFilter);
ServerFilter.VMargin(5.0f, &ServerFilter);
ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter);
static int s_BrFilterEmpty = 0;
if(pMenus->DoButton_CheckBox(&s_BrFilterEmpty, Localize("Has people playing"), SortHash&IServerBrowser::FILTER_EMPTY, &Button))
pFilter->SetFilter(SortHash^IServerBrowser::FILTER_EMPTY, Ping, Country, aGametype, aServerAddress);
ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter);
static int s_BrFilterSpectators = 0;
if(pMenus->DoButton_CheckBox(&s_BrFilterSpectators, Localize("Count players only"), SortHash&IServerBrowser::FILTER_SPECTATORS, &Button))
pFilter->SetFilter(SortHash^IServerBrowser::FILTER_SPECTATORS, Ping, Country, aGametype, aServerAddress);
ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter);
static int s_BrFilterFull = 0;
if(pMenus->DoButton_CheckBox(&s_BrFilterFull, Localize("Server not full"), SortHash&IServerBrowser::FILTER_FULL, &Button))
pFilter->SetFilter(SortHash^IServerBrowser::FILTER_FULL, Ping, Country, aGametype, aServerAddress);
ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter);
static int s_BrFilterFriends = 0;
if(pMenus->DoButton_CheckBox(&s_BrFilterFriends, Localize("Show friends only"), SortHash&IServerBrowser::FILTER_FRIENDS, &Button))
pFilter->SetFilter(SortHash^IServerBrowser::FILTER_FRIENDS, Ping, Country, aGametype, aServerAddress);
ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter);
static int s_BrFilterPw = 0;
if(pMenus->DoButton_CheckBox(&s_BrFilterPw, Localize("No password"), SortHash&IServerBrowser::FILTER_PW, &Button))
pFilter->SetFilter(SortHash^IServerBrowser::FILTER_PW, Ping, Country, aGametype, aServerAddress);
ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter);
static int s_BrFilterCompatversion = 0;
if(pMenus->DoButton_CheckBox(&s_BrFilterCompatversion, Localize("Compatible version"), SortHash&IServerBrowser::FILTER_COMPAT_VERSION, &Button))
pFilter->SetFilter(SortHash^IServerBrowser::FILTER_COMPAT_VERSION, Ping, Country, aGametype, aServerAddress);
ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter);
static int s_BrFilterPure = 0;
if(pMenus->DoButton_CheckBox(&s_BrFilterPure, Localize("Standard gametype"), SortHash&IServerBrowser::FILTER_PURE, &Button))
pFilter->SetFilter(SortHash^IServerBrowser::FILTER_PURE, Ping, Country, aGametype, aServerAddress);
ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter);
static int s_BrFilterPureMap = 0;
if(pMenus->DoButton_CheckBox(&s_BrFilterPureMap, Localize("Standard map"), SortHash&IServerBrowser::FILTER_PURE_MAP, &Button))
pFilter->SetFilter(SortHash^IServerBrowser::FILTER_PURE_MAP, Ping, Country, aGametype, aServerAddress);
ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter);
static int s_BrFilterGametypeStrict = 0;
if(pMenus->DoButton_CheckBox(&s_BrFilterGametypeStrict, Localize("Strict gametype filter"), SortHash&IServerBrowser::FILTER_GAMETYPE_STRICT, &Button))
pFilter->SetFilter(SortHash^IServerBrowser::FILTER_GAMETYPE_STRICT, Ping, Country, aGametype, aServerAddress);
ServerFilter.HSplitTop(5.0f, 0, &ServerFilter);
ServerFilter.HSplitTop(19.0f, &Button, &ServerFilter);
pMenus->UI()->DoLabelScaled(&Button, Localize("Game types:"), FontSize, -1);
Button.VSplitRight(60.0f, 0, &Button);
ServerFilter.HSplitTop(3.0f, 0, &ServerFilter);
static float Offset = 0.0f;
static int s_BrFilterGametype = 0;
if(pMenus->DoEditBox(&s_BrFilterGametype, &Button, aGametype, sizeof(aGametype), FontSize, &Offset))
pFilter->SetFilter(SortHash, Ping, Country, aGametype, aServerAddress);
{
ServerFilter.HSplitTop(19.0f, &Button, &ServerFilter);
CUIRect EditBox;
Button.VSplitRight(60.0f, &Button, &EditBox);
pMenus->UI()->DoLabelScaled(&Button, Localize("Maximum ping:"), FontSize, -1);
char aBuf[5];
str_format(aBuf, sizeof(aBuf), "%d", Ping);
static float Offset = 0.0f;
static int s_BrFilterPing = 0;
pMenus->DoEditBox(&s_BrFilterPing, &EditBox, aBuf, sizeof(aBuf), FontSize, &Offset);
int NewPing = clamp(str_toint(aBuf), 0, 999);
if(NewPing != Ping)
pFilter->SetFilter(SortHash, NewPing, Country, aGametype, aServerAddress);
}
// server address
ServerFilter.HSplitTop(3.0f, 0, &ServerFilter);
ServerFilter.HSplitTop(19.0f, &Button, &ServerFilter);
pMenus->UI()->DoLabelScaled(&Button, Localize("Server address:"), FontSize, -1);
Button.VSplitRight(60.0f, 0, &Button);
static float OffsetAddr = 0.0f;
static int s_BrFilterServerAddress = 0;
if(pMenus->DoEditBox(&s_BrFilterServerAddress, &Button, aServerAddress, sizeof(aServerAddress), FontSize, &OffsetAddr))
pFilter->SetFilter(SortHash, Ping, Country, aGametype, aServerAddress);
// player country
{
CUIRect Rect;
ServerFilter.HSplitTop(3.0f, 0, &ServerFilter);
ServerFilter.HSplitTop(26.0f, &Button, &ServerFilter);
Button.VSplitRight(60.0f, &Button, &Rect);
Button.HMargin(3.0f, &Button);
static int s_BrFilterCountry = 0;
if(pMenus->DoButton_CheckBox(&s_BrFilterCountry, Localize("Player country:"), SortHash&IServerBrowser::FILTER_COUNTRY, &Button))
pFilter->SetFilter(SortHash^IServerBrowser::FILTER_COUNTRY, Ping, Country, aGametype, aServerAddress);
float OldWidth = Rect.w;
Rect.w = Rect.h*2;
Rect.x += (OldWidth-Rect.w)/2.0f;
vec4 Color(1.0f, 1.0f, 1.0f, SortHash^IServerBrowser::FILTER_COUNTRY?1.0f: 0.5f);
pMenus->m_pClient->m_pCountryFlags->Render(Country, &Color, Rect.x, Rect.y, Rect.w, Rect.h);
static int s_BrFilterCountryIndex = 0;
if(SortHash^IServerBrowser::FILTER_COUNTRY && pMenus->UI()->DoButtonLogic(&s_BrFilterCountryIndex, "", 0, &Rect))
pMenus->m_Popup = POPUP_COUNTRY;
}
return 0;
}