Merge pull request #1825 from Zwelf/pr-enhance-cursor-movement

Added ctrl+arrows/backspace/delete keys for text input
This commit is contained in:
oy 2018-12-28 18:40:22 +01:00 committed by GitHub
commit 0643c5a43a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 62 additions and 14 deletions

View file

@ -139,6 +139,11 @@ void CChat::ConShowChat(IConsole::IResult *pResult, void *pUserData)
((CChat *)pUserData)->m_Show = pResult->GetInteger(0) != 0; ((CChat *)pUserData)->m_Show = pResult->GetInteger(0) != 0;
} }
void CChat::OnInit()
{
m_Input.Init(Input());
}
void CChat::OnConsoleInit() void CChat::OnConsoleInit()
{ {
Console()->Register("say", "r", CFGFLAG_CLIENT, ConSay, this, "Say in chat"); Console()->Register("say", "r", CFGFLAG_CLIENT, ConSay, this, "Say in chat");

View file

@ -81,6 +81,7 @@ public:
void Say(int Team, const char *pLine); void Say(int Team, const char *pLine);
virtual void OnInit();
virtual void OnReset(); virtual void OnReset();
virtual void OnConsoleInit(); virtual void OnConsoleInit();
virtual void OnStateChange(int NewState, int OldState); virtual void OnStateChange(int NewState, int OldState);

View file

@ -57,6 +57,7 @@ CGameConsole::CInstance::CInstance(int Type)
void CGameConsole::CInstance::Init(CGameConsole *pGameConsole) void CGameConsole::CInstance::Init(CGameConsole *pGameConsole)
{ {
m_pGameConsole = pGameConsole; m_pGameConsole = pGameConsole;
m_Input.Init(m_pGameConsole->Input());
}; };
void CGameConsole::CInstance::ClearBacklog() void CGameConsole::CInstance::ClearBacklog()

View file

@ -487,7 +487,7 @@ int CMenus::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrS
{ {
Len = str_length(pStr); Len = str_length(pStr);
int NumChars = Len; int NumChars = Len;
ReturnValue |= CLineInput::Manipulate(Input()->GetEvent(i), pStr, StrSize, StrSize, &Len, &s_AtIndex, &NumChars); ReturnValue |= CLineInput::Manipulate(Input()->GetEvent(i), pStr, StrSize, StrSize, &Len, &s_AtIndex, &NumChars, Input());
} }
} }
} }

View file

@ -1,11 +1,13 @@
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* (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. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */
#include <engine/keys.h> #include <engine/keys.h>
#include <engine/input.h>
#include "lineinput.h" #include "lineinput.h"
CLineInput::CLineInput() CLineInput::CLineInput()
{ {
Clear(); Clear();
m_pInput = 0;
} }
void CLineInput::Clear() void CLineInput::Clear()
@ -16,6 +18,11 @@ void CLineInput::Clear()
m_NumChars = 0; m_NumChars = 0;
} }
void CLineInput::Init(IInput *pInput)
{
m_pInput = pInput;
}
void CLineInput::Set(const char *pString) void CLineInput::Set(const char *pString)
{ {
str_copy(m_Str, pString, sizeof(m_Str)); str_copy(m_Str, pString, sizeof(m_Str));
@ -30,7 +37,15 @@ void CLineInput::Set(const char *pString)
} }
} }
bool CLineInput::Manipulate(IInput::CEvent Event, char *pStr, int StrMaxSize, int StrMaxChars, int *pStrLenPtr, int *pCursorPosPtr, int *pNumCharsPtr) bool CLineInput::CtrlStop(char c)
{
// jump to spaces and special ASCII characters
return ((32 <= c && c <= 47) || // !"#$%&'()*+,-./
(58 <= c && c <= 64) || // :;<=>?@
(91 <= c && c <= 96)); // [\]^_`
}
bool CLineInput::Manipulate(IInput::CEvent Event, char *pStr, int StrMaxSize, int StrMaxChars, int *pStrLenPtr, int *pCursorPosPtr, int *pNumCharsPtr, IInput *pInput)
{ {
int NumChars = *pNumCharsPtr; int NumChars = *pNumCharsPtr;
int CursorPos = *pCursorPosPtr; int CursorPos = *pCursorPosPtr;
@ -74,31 +89,54 @@ bool CLineInput::Manipulate(IInput::CEvent Event, char *pStr, int StrMaxSize, in
if(Event.m_Flags&IInput::FLAG_PRESS) if(Event.m_Flags&IInput::FLAG_PRESS)
{ {
int Key = Event.m_Key; int Key = Event.m_Key;
bool Ctrl = false;
#ifdef CONF_PLATFORM_MACOSX
if(pInput && (pInput->KeyIsPressed(KEY_LALT) || pInput->KeyIsPressed(KEY_RALT)))
#else
if(pInput && (pInput->KeyIsPressed(KEY_LCTRL) || pInput->KeyIsPressed(KEY_RCTRL)))
#endif
Ctrl = true;
if(Key == KEY_BACKSPACE && CursorPos > 0) if(Key == KEY_BACKSPACE && CursorPos > 0)
{ {
int NewCursorPos = str_utf8_rewind(pStr, CursorPos); int NewCursorPos = CursorPos;
do
{
NewCursorPos = str_utf8_rewind(pStr, NewCursorPos);
NumChars -= 1;
} while(Ctrl && NewCursorPos > 0 && !CtrlStop(pStr[NewCursorPos - 1]));
int CharSize = CursorPos-NewCursorPos; int CharSize = CursorPos-NewCursorPos;
mem_move(pStr+NewCursorPos, pStr+CursorPos, Len - NewCursorPos - CharSize + 1); // +1 == null term mem_move(pStr+NewCursorPos, pStr+CursorPos, Len - NewCursorPos - CharSize + 1); // +1 == null term
CursorPos = NewCursorPos; CursorPos = NewCursorPos;
Len -= CharSize; Len -= CharSize;
if(CharSize > 0)
--NumChars;
Changes = true; Changes = true;
} }
else if(Key == KEY_DELETE && CursorPos < Len) else if(Key == KEY_DELETE && CursorPos < Len)
{ {
int p = str_utf8_forward(pStr, CursorPos); int EndCursorPos = CursorPos;
int CharSize = p-CursorPos; do
{
EndCursorPos = str_utf8_forward(pStr, EndCursorPos);
NumChars -= 1;
} while(Ctrl && EndCursorPos < Len && !CtrlStop(pStr[EndCursorPos - 1]));
int CharSize = EndCursorPos - CursorPos;
mem_move(pStr + CursorPos, pStr + CursorPos + CharSize, Len - CursorPos - CharSize + 1); // +1 == null term mem_move(pStr + CursorPos, pStr + CursorPos + CharSize, Len - CursorPos - CharSize + 1); // +1 == null term
Len -= CharSize; Len -= CharSize;
if(CharSize > 0)
--NumChars;
Changes = true; Changes = true;
} }
else if(Key == KEY_LEFT && CursorPos > 0) else if(Key == KEY_LEFT && CursorPos > 0)
{
do
{
CursorPos = str_utf8_rewind(pStr, CursorPos); CursorPos = str_utf8_rewind(pStr, CursorPos);
} while(Ctrl && CursorPos > 0 && !CtrlStop(pStr[CursorPos - 1]));
}
else if(Key == KEY_RIGHT && CursorPos < Len) else if(Key == KEY_RIGHT && CursorPos < Len)
{
do
{
CursorPos = str_utf8_forward(pStr, CursorPos); CursorPos = str_utf8_forward(pStr, CursorPos);
} while(Ctrl && CursorPos < Len && !CtrlStop(pStr[CursorPos - 1]));
}
else if(Key == KEY_HOME) else if(Key == KEY_HOME)
CursorPos = 0; CursorPos = 0;
else if(Key == KEY_END) else if(Key == KEY_END)
@ -114,5 +152,5 @@ bool CLineInput::Manipulate(IInput::CEvent Event, char *pStr, int StrMaxSize, in
bool CLineInput::ProcessInput(IInput::CEvent e) bool CLineInput::ProcessInput(IInput::CEvent e)
{ {
return Manipulate(e, m_Str, MAX_SIZE, MAX_CHARS, &m_Len, &m_CursorPos, &m_NumChars); return Manipulate(e, m_Str, MAX_SIZE, MAX_CHARS, &m_Len, &m_CursorPos, &m_NumChars, m_pInput);
} }

View file

@ -17,8 +17,10 @@ class CLineInput
int m_Len; int m_Len;
int m_CursorPos; int m_CursorPos;
int m_NumChars; int m_NumChars;
IInput *m_pInput;
public: public:
static bool Manipulate(IInput::CEvent e, char *pStr, int StrMaxSize, int StrMaxChars, int *pStrLenPtr, int *pCursorPosPtr, int *pNumCharsPtr); static bool CtrlStop(char c);
static bool Manipulate(IInput::CEvent e, char *pStr, int StrMaxSize, int StrMaxChars, int *pStrLenPtr, int *pCursorPosPtr, int *pNumCharsPtr, IInput *pInput);
class CCallback class CCallback
{ {
@ -28,6 +30,7 @@ public:
}; };
CLineInput(); CLineInput();
void Init(IInput *pInput);
void Clear(); void Clear();
bool ProcessInput(IInput::CEvent e); bool ProcessInput(IInput::CEvent e);
void Set(const char *pString); void Set(const char *pString);

View file

@ -340,7 +340,7 @@ int CEditor::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned Str
{ {
Len = str_length(pStr); Len = str_length(pStr);
int NumChars = Len; int NumChars = Len;
ReturnValue |= CLineInput::Manipulate(Input()->GetEvent(i), pStr, StrSize, StrSize, &Len, &s_AtIndex, &NumChars); ReturnValue |= CLineInput::Manipulate(Input()->GetEvent(i), pStr, StrSize, StrSize, &Len, &s_AtIndex, &NumChars, Input());
} }
} }