From b37f77574ee71d6f2f63561dff3055522bdf3213 Mon Sep 17 00:00:00 2001 From: Zwelf Date: Thu, 1 Jun 2017 20:22:58 +0200 Subject: [PATCH] Added ctrl+arrows/backspace/delete keys for text input --- src/game/client/components/chat.cpp | 5 +++ src/game/client/components/chat.h | 1 + src/game/client/components/console.cpp | 1 + src/game/client/components/menus.cpp | 2 +- src/game/client/lineinput.cpp | 56 +++++++++++++++++++++----- src/game/client/lineinput.h | 5 ++- src/game/editor/editor.cpp | 2 +- 7 files changed, 58 insertions(+), 14 deletions(-) diff --git a/src/game/client/components/chat.cpp b/src/game/client/components/chat.cpp index 08362f55e..5e92c373e 100644 --- a/src/game/client/components/chat.cpp +++ b/src/game/client/components/chat.cpp @@ -136,6 +136,11 @@ void CChat::ConShowChat(IConsole::IResult *pResult, void *pUserData) ((CChat *)pUserData)->m_Show = pResult->GetInteger(0) != 0; } +void CChat::OnInit() +{ + m_Input.Init(Input()); +} + void CChat::OnConsoleInit() { Console()->Register("say", "r", CFGFLAG_CLIENT, ConSay, this, "Say in chat"); diff --git a/src/game/client/components/chat.h b/src/game/client/components/chat.h index aac6a558c..732a7b79a 100644 --- a/src/game/client/components/chat.h +++ b/src/game/client/components/chat.h @@ -81,6 +81,7 @@ public: void Say(int Team, const char *pLine); + virtual void OnInit(); virtual void OnReset(); virtual void OnConsoleInit(); virtual void OnStateChange(int NewState, int OldState); diff --git a/src/game/client/components/console.cpp b/src/game/client/components/console.cpp index d275f09cf..bec0c0c9c 100644 --- a/src/game/client/components/console.cpp +++ b/src/game/client/components/console.cpp @@ -57,6 +57,7 @@ CGameConsole::CInstance::CInstance(int Type) void CGameConsole::CInstance::Init(CGameConsole *pGameConsole) { m_pGameConsole = pGameConsole; + m_Input.Init(m_pGameConsole->Input()); }; void CGameConsole::CInstance::ClearBacklog() diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 36b7cdb0c..1fc6ecd30 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -473,7 +473,7 @@ int CMenus::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrS { Len = str_length(pStr); 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()); } } } diff --git a/src/game/client/lineinput.cpp b/src/game/client/lineinput.cpp index b60b0f8a8..a118aab93 100644 --- a/src/game/client/lineinput.cpp +++ b/src/game/client/lineinput.cpp @@ -1,11 +1,13 @@ /* (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 +#include #include "lineinput.h" CLineInput::CLineInput() { Clear(); + m_pInput = 0; } void CLineInput::Clear() @@ -16,6 +18,11 @@ void CLineInput::Clear() m_NumChars = 0; } +void CLineInput::Init(IInput *pInput) +{ + m_pInput = pInput; +} + void CLineInput::Set(const char *pString) { 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 CursorPos = *pCursorPosPtr; @@ -74,31 +89,50 @@ bool CLineInput::Manipulate(IInput::CEvent Event, char *pStr, int StrMaxSize, in if(Event.m_Flags&IInput::FLAG_PRESS) { int Key = Event.m_Key; + bool Ctrl = false; + if(pInput && (pInput->KeyIsPressed(KEY_LCTRL) || pInput->KeyIsPressed(KEY_RCTRL))) + Ctrl = true; 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; mem_move(pStr+NewCursorPos, pStr+CursorPos, Len - NewCursorPos - CharSize + 1); // +1 == null term CursorPos = NewCursorPos; Len -= CharSize; - if(CharSize > 0) - --NumChars; Changes = true; } else if(Key == KEY_DELETE && CursorPos < Len) { - int p = str_utf8_forward(pStr, CursorPos); - int CharSize = p-CursorPos; + int EndCursorPos = 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 Len -= CharSize; - if(CharSize > 0) - --NumChars; Changes = true; } else if(Key == KEY_LEFT && CursorPos > 0) - CursorPos = str_utf8_rewind(pStr, CursorPos); + { + do + { + CursorPos = str_utf8_rewind(pStr, CursorPos); + } while(Ctrl && CursorPos > 0 && !CtrlStop(pStr[CursorPos - 1])); + } else if(Key == KEY_RIGHT && CursorPos < Len) - CursorPos = str_utf8_forward(pStr, CursorPos); + { + do + { + CursorPos = str_utf8_forward(pStr, CursorPos); + } while(Ctrl && CursorPos < Len && !CtrlStop(pStr[CursorPos - 1])); + } else if(Key == KEY_HOME) CursorPos = 0; else if(Key == KEY_END) @@ -114,5 +148,5 @@ bool CLineInput::Manipulate(IInput::CEvent Event, char *pStr, int StrMaxSize, in 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); } diff --git a/src/game/client/lineinput.h b/src/game/client/lineinput.h index 5e1f1d74d..fae3a5ef4 100644 --- a/src/game/client/lineinput.h +++ b/src/game/client/lineinput.h @@ -17,8 +17,10 @@ class CLineInput int m_Len; int m_CursorPos; int m_NumChars; + IInput *m_pInput; 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 { @@ -28,6 +30,7 @@ public: }; CLineInput(); + void Init(IInput *pInput); void Clear(); bool ProcessInput(IInput::CEvent e); void Set(const char *pString); diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 413cfa716..a6c1be23f 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -340,7 +340,7 @@ int CEditor::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned Str { Len = str_length(pStr); 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()); } }