ime window position & ime input handling

This commit is contained in:
TsFreddie 2020-09-22 17:01:13 +01:00
parent 06b519398b
commit 387bc53030
8 changed files with 55 additions and 16 deletions

@ -1 +1 @@
Subproject commit 7c2ba39a9a8514790aac38fa4ac8000c610c3955
Subproject commit de46e0008be5c0e057e57343dceaafdc75385044

View file

@ -50,12 +50,16 @@ CInput::CInput()
m_pClipboardText = NULL;
m_CountEditingText = 0;
m_EditingTextLen = -1;
m_aEditingText[0] = 0;
}
void CInput::Init()
{
m_pGraphics = Kernel()->RequestInterface<IEngineGraphics>();
// increase ime instance counter for menu
SetIMEState(true);
MouseModeRelative();
}
@ -134,6 +138,8 @@ void CInput::NextFrame()
if(i >= KEY_LAST)
i = KEY_LAST-1;
mem_copy(m_aInputState, pState, i);
if(m_EditingTextLen == 0)
m_EditingTextLen = -1;
}
bool CInput::GetIMEState()
@ -147,8 +153,7 @@ void CInput::SetIMEState(bool Activate)
{
if(m_CountEditingText == 0)
SDL_StartTextInput();
else
m_CountEditingText++;
m_CountEditingText++;
}
else
{
@ -162,7 +167,7 @@ void CInput::SetIMEState(bool Activate)
const char* CInput::GetIMECandidate()
{
if (str_length(m_aEditingText))
if(m_EditingTextLen > 0)
return m_aEditingText;
else
return "";
@ -173,6 +178,24 @@ int CInput::GetEditingCursor()
return m_EditingCursor;
}
void CInput::SetEditingPosition(float X, float Y)
{
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
int ScreenWidth = Graphics()->ScreenWidth();
int ScreenHeight = Graphics()->ScreenHeight();
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
vec2 ScreenScale = vec2(ScreenWidth/(ScreenX1-ScreenX0), ScreenHeight/(ScreenY1-ScreenY0));
SDL_Rect ImeWindowRect;
ImeWindowRect.x = X * ScreenScale.x;
ImeWindowRect.y = Y * ScreenScale.y;
ImeWindowRect.h = 60;
ImeWindowRect.w = 1000;
SDL_SetTextInputRect(&ImeWindowRect);
}
int CInput::Update()
{
// keep the counter between 1..0xFFFF, 0 means not pressed
@ -202,7 +225,8 @@ int CInput::Update()
{
case SDL_TEXTEDITING:
{
if(str_length(Event.edit.text))
m_EditingTextLen = str_length(Event.edit.text);
if(m_EditingTextLen)
{
str_copy(m_aEditingText, Event.edit.text, sizeof(m_aEditingText));
m_EditingCursor = 0;
@ -315,7 +339,7 @@ int CInput::Update()
return 1;
}
if(Scancode > KEY_FIRST && Scancode < g_MaxKeys && !IgnoreKeys && m_CountEditingText == 0)
if(Scancode > KEY_FIRST && Scancode < g_MaxKeys && !IgnoreKeys && (!SDL_IsTextInputActive() || m_EditingTextLen == -1))
{
if(Action&IInput::FLAG_PRESS)
{

View file

@ -28,6 +28,7 @@ class CInput : public IEngineInput
// IME support
int m_CountEditingText;
char m_aEditingText[32];
int m_EditingTextLen;
int m_EditingCursor;
bool KeyState(int Key) const;
@ -58,6 +59,7 @@ public:
virtual void SetIMEState(bool Activate);
virtual const char* GetIMECandidate();
virtual int GetEditingCursor();
virtual void SetEditingPosition(float X, float Y);
};
#endif

View file

@ -72,6 +72,7 @@ public:
virtual void SetIMEState(bool Activate) = 0;
virtual const char* GetIMECandidate() = 0;
virtual int GetEditingCursor() = 0;
virtual void SetEditingPosition(float X, float Y) = 0;
};

View file

@ -16,6 +16,7 @@
#include <game/client/gameclient.h>
#include <game/client/components/console.h>
#include <game/client/components/scoreboard.h>
#include <game/client/components/sounds.h>
#include <game/localization.h>
@ -35,6 +36,7 @@ CChat::CChat()
#include <game/server/ddracechat.h>
m_Commands.sort_range();
m_Mode = MODE_NONE;
Reset();
}
@ -69,7 +71,6 @@ void CChat::Reset()
m_PrevShowChat = false;
m_ReverseTAB = false;
m_Mode = MODE_NONE;
m_Show = false;
m_InputUpdate = false;
m_ChatStringOffset = 0;
@ -81,7 +82,8 @@ void CChat::Reset()
m_PendingChatCounter = 0;
m_LastChatSend = 0;
m_CurrentLine = 0;
m_Mode = MODE_NONE;
DisableMode();
for(int i = 0; i < CHAT_NUM; ++i)
m_aLastSoundPlayed[i] = 0;
@ -249,13 +251,10 @@ bool CChat::OnInput(IInput::CEvent Event)
if(Event.m_Flags&IInput::FLAG_PRESS && Event.m_Key == KEY_ESCAPE)
{
m_Mode = MODE_NONE;
DisableMode();
m_pClient->OnRelease();
if(g_Config.m_ClChatReset)
m_Input.Clear();
// abort text editing when pressing escape
Input()->SetIMEState(false);
}
else if(Event.m_Flags&IInput::FLAG_PRESS && (Event.m_Key == KEY_RETURN || Event.m_Key == KEY_KP_ENTER))
{
@ -282,12 +281,9 @@ bool CChat::OnInput(IInput::CEvent Event)
}
}
m_pHistoryEntry = 0x0;
m_Mode = MODE_NONE;
DisableMode();
m_pClient->OnRelease();
m_Input.Clear();
// stop text editing after send chat.
Input()->SetIMEState(false);
}
if(Event.m_Flags&IInput::FLAG_PRESS && Event.m_Key == KEY_TAB)
{
@ -516,6 +512,15 @@ void CChat::EnableMode(int Team)
}
}
void CChat::DisableMode()
{
if(m_Mode != MODE_NONE)
{
Input()->SetIMEState(false);
m_Mode = MODE_NONE;
}
}
void CChat::OnMessage(int MsgType, void *pRawMsg)
{
if(MsgType == NETMSGTYPE_SV_CHAT)
@ -1025,6 +1030,8 @@ void CChat::OnRender()
Marker.m_X -= MarkerOffset;
TextRender()->TextEx(&Marker, "|", -1);
TextRender()->TextEx(&Cursor, m_Input.GetString(Editing)+m_Input.GetCursorOffset(Editing), -1);
if(m_pClient->m_pGameConsole->IsClosed())
Input()->SetEditingPosition(Marker.m_X, Marker.m_Y + Marker.m_FontSize);
}
#if defined(CONF_VIDEORECORDER)

View file

@ -100,6 +100,7 @@ public:
bool IsActive() const { return m_Mode != MODE_NONE; }
void AddLine(int ClientID, int Team, const char *pLine);
void EnableMode(int Team);
void DisableMode();
void Say(int Team, const char *pLine);
void SayChat(const char *pLine);
void RegisterCommand(const char *pName, const char *pParams, int flags, const char *pHelp);

View file

@ -618,6 +618,7 @@ void CGameConsole::OnRender()
Marker.m_LineWidth = -1;
TextRender()->TextEx(&Marker, "|", -1);
TextRender()->TextEx(&Cursor, aInputString+pConsole->m_Input.GetCursorOffset(Editing), -1);
Input()->SetEditingPosition(Marker.m_X, Marker.m_Y + Marker.m_FontSize);
// render possible commands
if(m_ConsoleType == CONSOLETYPE_LOCAL || Client()->RconAuthed())

View file

@ -513,7 +513,10 @@ int CMenus::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrS
if((2*time_get()/time_freq()) % 2) // make it blink
UI()->DoLabel(&Textbox, "|", FontSize, -1);
Input()->SetEditingPosition(Textbox.x, Textbox.y + FontSize);
}
UI()->ClipDisable();
return ReturnValue;