mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-09 09:38:19 +00:00
Add touch support to emoticon selector and spectator menu
Support using emoticon selector and spectator menu with touch inputs. Touching in the emoticon selector activates the selected (eye) emote and closes the emoticon selector. The spectator menu is kept open when using it for more convenience. The emoticon selector and spectator menu can be closed by touching anywhere outside of them. Additionally, the emoticon selector and specator menu can now be closed by pressing the Escape key (i.e. the back button on Android). This made it necessary to change the order of the components for input handling, so the ingame menu will handle the Escape key after the emoticon selector and spectator menu. This also means that the Escape key can now be used to close the selector/menu when they are stuck open, which was previously delayed until ingame menu or console were opened and closed.
This commit is contained in:
parent
3cf3e2339d
commit
3bda76ff1f
|
@ -41,6 +41,7 @@ void CEmoticon::OnReset()
|
|||
m_Active = false;
|
||||
m_SelectedEmote = -1;
|
||||
m_SelectedEyeEmote = -1;
|
||||
m_TouchPressedOutside = false;
|
||||
}
|
||||
|
||||
void CEmoticon::OnRelease()
|
||||
|
@ -58,6 +59,16 @@ bool CEmoticon::OnCursorMove(float x, float y, IInput::ECursorType CursorType)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CEmoticon::OnInput(const IInput::CEvent &Event)
|
||||
{
|
||||
if(IsActive() && Event.m_Flags & IInput::FLAG_PRESS && Event.m_Key == KEY_ESCAPE)
|
||||
{
|
||||
OnRelease();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CEmoticon::OnRender()
|
||||
{
|
||||
if(Client()->State() != IClient::STATE_ONLINE && Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
||||
|
@ -65,6 +76,13 @@ void CEmoticon::OnRender()
|
|||
|
||||
if(!m_Active)
|
||||
{
|
||||
if(m_TouchPressedOutside)
|
||||
{
|
||||
m_SelectedEmote = -1;
|
||||
m_SelectedEyeEmote = -1;
|
||||
m_TouchPressedOutside = false;
|
||||
}
|
||||
|
||||
if(m_WasActive && m_SelectedEmote != -1)
|
||||
Emote(m_SelectedEmote);
|
||||
if(m_WasActive && m_SelectedEyeEmote != -1)
|
||||
|
@ -82,6 +100,29 @@ void CEmoticon::OnRender()
|
|||
|
||||
m_WasActive = true;
|
||||
|
||||
const CUIRect Screen = *Ui()->Screen();
|
||||
|
||||
const bool WasTouchPressed = m_TouchState.m_AnyPressed;
|
||||
Ui()->UpdateTouchState(m_TouchState);
|
||||
if(m_TouchState.m_AnyPressed)
|
||||
{
|
||||
const vec2 TouchPos = (m_TouchState.m_PrimaryPosition - vec2(0.5f, 0.5f)) * Screen.Size();
|
||||
const float TouchCenterDistance = length(TouchPos);
|
||||
if(TouchCenterDistance <= 170.0f)
|
||||
{
|
||||
m_SelectorMouse = TouchPos;
|
||||
}
|
||||
else if(TouchCenterDistance > 190.0f)
|
||||
{
|
||||
m_TouchPressedOutside = true;
|
||||
}
|
||||
}
|
||||
else if(WasTouchPressed)
|
||||
{
|
||||
m_Active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(length(m_SelectorMouse) > 170.0f)
|
||||
m_SelectorMouse = normalize(m_SelectorMouse) * 170.0f;
|
||||
|
||||
|
@ -96,8 +137,6 @@ void CEmoticon::OnRender()
|
|||
else if(length(m_SelectorMouse) > 40.0f)
|
||||
m_SelectedEyeEmote = (int)(SelectedAngle / (2 * pi) * NUM_EMOTES);
|
||||
|
||||
CUIRect Screen = *Ui()->Screen();
|
||||
|
||||
Ui()->MapScreen();
|
||||
|
||||
Graphics()->BlendNormal();
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
#define GAME_CLIENT_COMPONENTS_EMOTICON_H
|
||||
#include <base/vmath.h>
|
||||
#include <engine/console.h>
|
||||
|
||||
#include <game/client/component.h>
|
||||
#include <game/client/ui.h>
|
||||
|
||||
class CEmoticon : public CComponent
|
||||
{
|
||||
|
@ -15,6 +17,9 @@ class CEmoticon : public CComponent
|
|||
int m_SelectedEmote;
|
||||
int m_SelectedEyeEmote;
|
||||
|
||||
CUi::CTouchState m_TouchState;
|
||||
bool m_TouchPressedOutside;
|
||||
|
||||
static void ConKeyEmoticon(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConEmote(IConsole::IResult *pResult, void *pUserData);
|
||||
|
||||
|
@ -27,9 +32,12 @@ public:
|
|||
virtual void OnRender() override;
|
||||
virtual void OnRelease() override;
|
||||
virtual bool OnCursorMove(float x, float y, IInput::ECursorType CursorType) override;
|
||||
virtual bool OnInput(const IInput::CEvent &Event) override;
|
||||
|
||||
void Emote(int Emoticon);
|
||||
void EyeEmote(int EyeEmote);
|
||||
|
||||
bool IsActive() const { return m_Active; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -186,6 +186,16 @@ bool CSpectator::OnCursorMove(float x, float y, IInput::ECursorType CursorType)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CSpectator::OnInput(const IInput::CEvent &Event)
|
||||
{
|
||||
if(IsActive() && Event.m_Flags & IInput::FLAG_PRESS && Event.m_Key == KEY_ESCAPE)
|
||||
{
|
||||
OnRelease();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CSpectator::OnRelease()
|
||||
{
|
||||
OnReset();
|
||||
|
@ -258,8 +268,6 @@ void CSpectator::OnRender()
|
|||
float BoxMove = -10.0f;
|
||||
float BoxOffset = 0.0f;
|
||||
|
||||
const bool MousePressed = Input()->KeyPress(KEY_MOUSE_1);
|
||||
|
||||
for(const auto &pInfo : m_pClient->m_Snap.m_apInfoByDDTeamName)
|
||||
{
|
||||
if(!pInfo || pInfo->m_Team == TEAM_SPECTATORS)
|
||||
|
@ -293,14 +301,42 @@ void CSpectator::OnRender()
|
|||
ObjWidth = 600.0f;
|
||||
}
|
||||
|
||||
const vec2 ScreenSize = vec2(Width, Height);
|
||||
const vec2 ScreenCenter = ScreenSize / 2.0f;
|
||||
CUIRect SpectatorRect = {Width / 2.0f - ObjWidth, Height / 2.0f - 300.0f, ObjWidth * 2.0f, 600.0f};
|
||||
CUIRect SpectatorMouseRect;
|
||||
SpectatorRect.Margin(20.0f, &SpectatorMouseRect);
|
||||
|
||||
const bool WasTouchPressed = m_TouchState.m_AnyPressed;
|
||||
Ui()->UpdateTouchState(m_TouchState);
|
||||
if(m_TouchState.m_AnyPressed)
|
||||
{
|
||||
const vec2 TouchPos = (m_TouchState.m_PrimaryPosition - vec2(0.5f, 0.5f)) * ScreenSize;
|
||||
if(SpectatorMouseRect.Inside(ScreenCenter + TouchPos))
|
||||
{
|
||||
m_SelectorMouse = TouchPos;
|
||||
}
|
||||
}
|
||||
else if(WasTouchPressed)
|
||||
{
|
||||
const vec2 TouchPos = (m_TouchState.m_PrimaryPosition - vec2(0.5f, 0.5f)) * ScreenSize;
|
||||
if(!SpectatorRect.Inside(ScreenCenter + TouchPos))
|
||||
{
|
||||
OnRelease();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Graphics()->MapScreen(0, 0, Width, Height);
|
||||
|
||||
Graphics()->DrawRect(Width / 2.0f - ObjWidth, Height / 2.0f - 300.0f, ObjWidth * 2, 600.0f, ColorRGBA(0.0f, 0.0f, 0.0f, 0.3f), IGraphics::CORNER_ALL, 20.0f);
|
||||
SpectatorRect.Draw(ColorRGBA(0.0f, 0.0f, 0.0f, 0.3f), IGraphics::CORNER_ALL, 20.0f);
|
||||
|
||||
// clamp mouse position to selector area
|
||||
m_SelectorMouse.x = clamp(m_SelectorMouse.x, -(ObjWidth - 20.0f), ObjWidth - 20.0f);
|
||||
m_SelectorMouse.y = clamp(m_SelectorMouse.y, -280.0f, 280.0f);
|
||||
|
||||
const bool MousePressed = Input()->KeyPress(KEY_MOUSE_1) || m_TouchState.m_PrimaryPressed;
|
||||
|
||||
// draw selections
|
||||
if((Client()->State() == IClient::STATE_DEMOPLAYBACK && m_pClient->m_DemoSpecId == SPEC_FREEVIEW) ||
|
||||
(Client()->State() != IClient::STATE_DEMOPLAYBACK && m_pClient->m_Snap.m_SpecInfo.m_SpectatorId == SPEC_FREEVIEW))
|
||||
|
@ -543,7 +579,7 @@ void CSpectator::OnRender()
|
|||
}
|
||||
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
RenderTools()->RenderCursor(m_SelectorMouse + vec2(Width, Height) / 2, 48.0f);
|
||||
RenderTools()->RenderCursor(ScreenCenter + m_SelectorMouse, 48.0f);
|
||||
}
|
||||
|
||||
void CSpectator::OnReset()
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <engine/console.h>
|
||||
|
||||
#include <game/client/component.h>
|
||||
#include <game/client/ui.h>
|
||||
|
||||
class CSpectator : public CComponent
|
||||
{
|
||||
|
@ -21,6 +22,8 @@ class CSpectator : public CComponent
|
|||
int m_SelectedSpectatorId;
|
||||
vec2 m_SelectorMouse;
|
||||
|
||||
CUi::CTouchState m_TouchState;
|
||||
|
||||
float m_MultiViewActivateDelay;
|
||||
|
||||
bool CanChangeSpectator();
|
||||
|
@ -39,12 +42,15 @@ public:
|
|||
|
||||
virtual void OnConsoleInit() override;
|
||||
virtual bool OnCursorMove(float x, float y, IInput::ECursorType CursorType) override;
|
||||
virtual bool OnInput(const IInput::CEvent &Event) override;
|
||||
virtual void OnRender() override;
|
||||
virtual void OnRelease() override;
|
||||
virtual void OnReset() override;
|
||||
|
||||
void Spectate(int SpectatorId);
|
||||
void SpectateClosest();
|
||||
|
||||
bool IsActive() const { return m_Active; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -160,9 +160,9 @@ void CGameClient::OnConsoleInit()
|
|||
&m_GameConsole,
|
||||
&m_Chat, // chat has higher prio, due to that you can quit it by pressing esc
|
||||
&m_Motd, // for pressing esc to remove it
|
||||
&m_Menus,
|
||||
&m_Spectator,
|
||||
&m_Emoticon,
|
||||
&m_Menus,
|
||||
&m_Controls,
|
||||
&m_Binds});
|
||||
|
||||
|
|
Loading…
Reference in a new issue