Allow binding with modifiers in settings

This commit is contained in:
Learath 2019-04-28 20:22:19 +03:00
parent 1da935f4c1
commit 66c89eafb2
5 changed files with 46 additions and 19 deletions

View file

@ -43,11 +43,11 @@ public:
void UnbindAll(); void UnbindAll();
const char *Get(int KeyID, int Modifier); const char *Get(int KeyID, int Modifier);
void GetKey(const char *pBindStr, char *aBuf, unsigned BufSize); void GetKey(const char *pBindStr, char *aBuf, unsigned BufSize);
int GetModifierMask(IInput *i);
int GetModifierMaskOfKey(int Key);
bool ModifierMatchesKey(int Modifier, int Key);
const char *GetModifierName(int Modifier);
int GetBindSlot(const char *pBindString, int *Modifier); int GetBindSlot(const char *pBindString, int *Modifier);
static int GetModifierMask(IInput *i);
static int GetModifierMaskOfKey(int Key);
static bool ModifierMatchesKey(int Modifier, int Key);
static const char *GetModifierName(int Modifier);
virtual void OnConsoleInit(); virtual void OnConsoleInit();
virtual bool OnInput(IInput::CEvent Event); virtual bool OnInput(IInput::CEvent Event);

View file

@ -26,6 +26,7 @@
#include <game/generated/protocol.h> #include <game/generated/protocol.h>
#include <game/generated/client_data.h> #include <game/generated/client_data.h>
#include <game/client/components/binds.h>
#include <game/client/components/sounds.h> #include <game/client/components/sounds.h>
#include <game/client/gameclient.h> #include <game/client/gameclient.h>
#include <game/client/lineinput.h> #include <game/client/lineinput.h>
@ -579,7 +580,7 @@ float CMenus::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current)
return ReturnValue; return ReturnValue;
} }
int CMenus::DoKeyReader(void *pID, const CUIRect *pRect, int Key) int CMenus::DoKeyReader(void *pID, const CUIRect *pRect, int Key, int Modifier, int *NewModifier)
{ {
// process // process
static void *pGrabbedID = 0; static void *pGrabbedID = 0;
@ -587,6 +588,7 @@ int CMenus::DoKeyReader(void *pID, const CUIRect *pRect, int Key)
static int ButtonUsed = 0; static int ButtonUsed = 0;
int Inside = UI()->MouseInside(pRect); int Inside = UI()->MouseInside(pRect);
int NewKey = Key; int NewKey = Key;
*NewModifier = Modifier;
if(!UI()->MouseButton(0) && !UI()->MouseButton(1) && pGrabbedID == pID) if(!UI()->MouseButton(0) && !UI()->MouseButton(1) && pGrabbedID == pID)
MouseReleased = true; MouseReleased = true;
@ -597,7 +599,10 @@ int CMenus::DoKeyReader(void *pID, const CUIRect *pRect, int Key)
{ {
// abort with escape key // abort with escape key
if(m_Binder.m_Key.m_Key != KEY_ESCAPE) if(m_Binder.m_Key.m_Key != KEY_ESCAPE)
{
NewKey = m_Binder.m_Key.m_Key; NewKey = m_Binder.m_Key.m_Key;
*NewModifier = m_Binder.m_Modifier;
}
m_Binder.m_GotKey = false; m_Binder.m_GotKey = false;
UI()->SetActiveItem(0); UI()->SetActiveItem(0);
MouseReleased = false; MouseReleased = false;
@ -639,10 +644,18 @@ int CMenus::DoKeyReader(void *pID, const CUIRect *pRect, int Key)
DoButton_KeySelect(pID, "???", 0, pRect); DoButton_KeySelect(pID, "???", 0, pRect);
else else
{ {
if(Key == 0) if(Key)
DoButton_KeySelect(pID, "", 0, pRect); {
char aBuf[64];
if(*NewModifier)
str_format(aBuf, sizeof(aBuf), "%s+%s", CBinds::GetModifierName(*NewModifier), Input()->KeyName(Key));
else
str_format(aBuf, sizeof(aBuf), "%s", Input()->KeyName(Key));
DoButton_KeySelect(pID, aBuf, 0, pRect);
}
else else
DoButton_KeySelect(pID, Input()->KeyName(Key), 0, pRect); DoButton_KeySelect(pID, "", 0, pRect);
} }
return NewKey; return NewKey;
} }
@ -799,7 +812,7 @@ int CMenus::RenderMenubar(CUIRect r)
Box.VSplitRight(10.0f, &Box, &Button); Box.VSplitRight(10.0f, &Box, &Button);
Box.VSplitRight(33.0f, &Box, &Button); Box.VSplitRight(33.0f, &Box, &Button);
static int s_SettingsButton=0; static int s_SettingsButton=0;
if(DoButton_MenuTab(&s_SettingsButton, "\xEE\xA2\xB8", m_ActivePage==PAGE_SETTINGS, &Button, CUI::CORNER_T)) if(DoButton_MenuTab(&s_SettingsButton, "\xEE\xA2\xB8", m_ActivePage==PAGE_SETTINGS, &Button, CUI::CORNER_T))
NewPage = PAGE_SETTINGS; NewPage = PAGE_SETTINGS;
@ -1909,7 +1922,7 @@ void CMenus::RenderUpdating(const char *pCaption, int current, int total)
CUIRect Screen = *UI()->Screen(); CUIRect Screen = *UI()->Screen();
Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h); Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h);
Graphics()->BlendNormal(); Graphics()->BlendNormal();
RenderBackground(); RenderBackground();

View file

@ -21,6 +21,7 @@ public:
bool m_TakeKey; bool m_TakeKey;
bool m_GotKey; bool m_GotKey;
IInput::CEvent m_Key; IInput::CEvent m_Key;
int m_Modifier;
CMenusKeyBinder(); CMenusKeyBinder();
virtual bool OnInput(IInput::CEvent Event); virtual bool OnInput(IInput::CEvent Event);
}; };
@ -71,7 +72,7 @@ class CMenus : public CComponent
float DoScrollbarV(const void *pID, const CUIRect *pRect, float Current); float DoScrollbarV(const void *pID, const CUIRect *pRect, float Current);
float DoScrollbarH(const void *pID, const CUIRect *pRect, float Current); float DoScrollbarH(const void *pID, const CUIRect *pRect, float Current);
void DoButton_KeySelect(const void *pID, const char *pText, int Checked, const CUIRect *pRect); void DoButton_KeySelect(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
int DoKeyReader(void *pID, const CUIRect *pRect, int Key); int DoKeyReader(void *pID, const CUIRect *pRect, int Key, int Modifier, int *NewModifier);
//static int ui_do_key_reader(void *id, const CUIRect *rect, int key); //static int ui_do_key_reader(void *id, const CUIRect *rect, int key);
void UiDoGetButtons(int Start, int Stop, CUIRect View, CUIRect ScopeView); void UiDoGetButtons(int Start, int Stop, CUIRect View, CUIRect ScopeView);
@ -366,7 +367,7 @@ public:
CGhostItem() : m_Slot(-1), m_Own(false) { m_aFilename[0] = 0; } CGhostItem() : m_Slot(-1), m_Own(false) { m_aFilename[0] = 0; }
bool operator<(const CGhostItem &Other) { return m_Time < Other.m_Time; } bool operator<(const CGhostItem &Other) { return m_Time < Other.m_Time; }
bool Active() const { return m_Slot != -1; } bool Active() const { return m_Slot != -1; }
bool HasFile() const { return m_aFilename[0]; } bool HasFile() const { return m_aFilename[0]; }
}; };

View file

@ -36,17 +36,29 @@ CMenusKeyBinder::CMenusKeyBinder()
{ {
m_TakeKey = false; m_TakeKey = false;
m_GotKey = false; m_GotKey = false;
m_Modifier = 0;
} }
bool CMenusKeyBinder::OnInput(IInput::CEvent Event) bool CMenusKeyBinder::OnInput(IInput::CEvent Event)
{ {
if(m_TakeKey) if(m_TakeKey)
{ {
if(Event.m_Flags&IInput::FLAG_PRESS) int TriggeringEvent = (Event.m_Key == KEY_MOUSE_1) ? IInput::FLAG_PRESS : IInput::FLAG_RELEASE;
if(Event.m_Flags&TriggeringEvent)
{ {
m_Key = Event; m_Key = Event;
m_GotKey = true; m_GotKey = true;
m_TakeKey = false; m_TakeKey = false;
int Mask = CBinds::GetModifierMask(Input());
m_Modifier = 0;
while(!(Mask&1))
{
Mask >>= 1;
m_Modifier++;
}
if(CBinds::ModifierMatchesKey(m_Modifier, Event.m_Key))
m_Modifier = 0;
} }
return true; return true;
} }
@ -735,14 +747,14 @@ void CMenus::UiDoGetButtons(int Start, int Stop, CUIRect View, CUIRect ScopeView
str_format(aBuf, sizeof(aBuf), "%s:", (const char *)Key.m_Name); str_format(aBuf, sizeof(aBuf), "%s:", (const char *)Key.m_Name);
UI()->DoLabelScaled(&Label, aBuf, 13.0f, -1); UI()->DoLabelScaled(&Label, aBuf, 13.0f, -1);
int OldId = Key.m_KeyId; int OldId = Key.m_KeyId, OldModifier = Key.m_Modifier, NewModifier;
int NewId = DoKeyReader((void *)&gs_aKeys[i].m_Name, &Button, OldId); int NewId = DoKeyReader((void *)&gs_aKeys[i].m_Name, &Button, OldId, OldModifier, &NewModifier);
if(NewId != OldId) if(NewId != OldId || NewModifier != OldModifier)
{ {
if(OldId != 0 || NewId == 0) if(OldId != 0 || NewId == 0)
m_pClient->m_pBinds->Bind(OldId, ""); m_pClient->m_pBinds->Bind(OldId, "", false, OldModifier);
if(NewId != 0) if(NewId != 0)
m_pClient->m_pBinds->Bind(NewId, gs_aKeys[i].m_pCommand); m_pClient->m_pBinds->Bind(NewId, gs_aKeys[i].m_pCommand, false, NewModifier);
} }
} }
@ -1060,7 +1072,7 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView)
g_Config.m_GfxEnableTextureUnitOptimization ^= 1; g_Config.m_GfxEnableTextureUnitOptimization ^= 1;
} }
} }
// check if the new settings require a restart // check if the new settings require a restart
if(CheckSettings) if(CheckSettings)
{ {

View file

@ -201,6 +201,7 @@ void CGameClient::OnConsoleInit()
m_All.Add(&gs_Statboard); m_All.Add(&gs_Statboard);
m_All.Add(m_pMotd); m_All.Add(m_pMotd);
m_All.Add(m_pMenus); m_All.Add(m_pMenus);
m_All.Add(&m_pMenus->m_Binder);
m_All.Add(m_pGameConsole); m_All.Add(m_pGameConsole);
// build the input stack // build the input stack