Make edit boxes respond to string input (IME) (#11156)

Make edit boxes respond to string input events (introduced in minetest/irrlicht#23) that are usually triggered by entering text with an IME.
This commit is contained in:
yw05 2021-04-05 15:56:29 +02:00 committed by GitHub
parent 2332527765
commit 85163b531f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 27 deletions

@ -17,6 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include "IrrCompileConfig.h"
#include "guiChatConsole.h" #include "guiChatConsole.h"
#include "chat.h" #include "chat.h"
#include "client/client.h" #include "client/client.h"
@ -618,6 +619,13 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
m_chat_backend->scroll(rows); m_chat_backend->scroll(rows);
} }
} }
#if (IRRLICHT_VERSION_MT_REVISION >= 2)
else if(event.EventType == EET_STRING_INPUT_EVENT)
{
prompt.input(std::wstring(event.StringInput.Str->c_str()));
return true;
}
#endif
return Parent ? Parent->OnEvent(event) : false; return Parent ? Parent->OnEvent(event) : false;
} }

@ -72,6 +72,8 @@ public:
virtual void setVisible(bool visible); virtual void setVisible(bool visible);
virtual bool acceptsIME() { return true; }
private: private:
void reformatConsole(); void reformatConsole();
void recalculateConsolePosition(); void recalculateConsolePosition();

@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "guiEditBox.h" #include "guiEditBox.h"
#include "IrrCompileConfig.h"
#include "IGUISkin.h" #include "IGUISkin.h"
#include "IGUIEnvironment.h" #include "IGUIEnvironment.h"
#include "IGUIFont.h" #include "IGUIFont.h"
@ -216,6 +217,11 @@ bool GUIEditBox::OnEvent(const SEvent &event)
if (processMouse(event)) if (processMouse(event))
return true; return true;
break; break;
#if (IRRLICHT_VERSION_MT_REVISION >= 2)
case EET_STRING_INPUT_EVENT:
inputString(*event.StringInput.Str);
return true;
#endif
default: default:
break; break;
} }
@ -669,40 +675,45 @@ bool GUIEditBox::onKeyDelete(const SEvent &event, s32 &mark_begin, s32 &mark_end
} }
void GUIEditBox::inputChar(wchar_t c) void GUIEditBox::inputChar(wchar_t c)
{
if (c == 0)
return;
core::stringw s(&c, 1);
inputString(s);
}
void GUIEditBox::inputString(const core::stringw &str)
{ {
if (!isEnabled() || !m_writable) if (!isEnabled() || !m_writable)
return; return;
if (c != 0) { u32 len = str.size();
if (Text.size() < m_max || m_max == 0) { if (Text.size()+len <= m_max || m_max == 0) {
core::stringw s; core::stringw s;
if (m_mark_begin != m_mark_end) {
// replace marked text
s32 real_begin = m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end;
s32 real_end = m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin;
if (m_mark_begin != m_mark_end) { s = Text.subString(0, real_begin);
// clang-format off s.append(str);
// replace marked text s.append(Text.subString(real_end, Text.size() - real_end));
s32 real_begin = m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end; Text = s;
s32 real_end = m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin; m_cursor_pos = real_begin + len;
} else {
s = Text.subString(0, real_begin); // append string
s.append(c); s = Text.subString(0, m_cursor_pos);
s.append(Text.subString(real_end, Text.size() - real_end)); s.append(str);
Text = s; s.append(Text.subString(m_cursor_pos,
m_cursor_pos = real_begin + 1; Text.size() - m_cursor_pos));
// clang-format on Text = s;
} else { m_cursor_pos += len;
// add new character
s = Text.subString(0, m_cursor_pos);
s.append(c);
s.append(Text.subString(m_cursor_pos,
Text.size() - m_cursor_pos));
Text = s;
++m_cursor_pos;
}
m_blink_start_time = porting::getTimeMs();
setTextMarkers(0, 0);
} }
m_blink_start_time = porting::getTimeMs();
setTextMarkers(0, 0);
} }
breakText(); breakText();
sendGuiEvent(EGET_EDITBOX_CHANGED); sendGuiEvent(EGET_EDITBOX_CHANGED);
calculateScrollPos(); calculateScrollPos();

@ -138,6 +138,8 @@ public:
virtual void deserializeAttributes( virtual void deserializeAttributes(
io::IAttributes *in, io::SAttributeReadWriteOptions *options); io::IAttributes *in, io::SAttributeReadWriteOptions *options);
virtual bool acceptsIME() { return isEnabled() && m_writable; };
protected: protected:
virtual void breakText() = 0; virtual void breakText() = 0;
@ -156,6 +158,7 @@ protected:
virtual s32 getCursorPos(s32 x, s32 y) = 0; virtual s32 getCursorPos(s32 x, s32 y) = 0;
bool processKey(const SEvent &event); bool processKey(const SEvent &event);
virtual void inputString(const core::stringw &str);
virtual void inputChar(wchar_t c); virtual void inputChar(wchar_t c);
//! returns the line number that the cursor is on //! returns the line number that the cursor is on