From 85163b531f283c52111c3964fd382e4ed1dafeb8 Mon Sep 17 00:00:00 2001 From: yw05 <37980625+yw05@users.noreply.github.com> Date: Mon, 5 Apr 2021 15:56:29 +0200 Subject: [PATCH] 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. --- src/gui/guiChatConsole.cpp | 8 +++++ src/gui/guiChatConsole.h | 2 ++ src/gui/guiEditBox.cpp | 65 ++++++++++++++++++++++---------------- src/gui/guiEditBox.h | 3 ++ 4 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index b7af0ca0f..baaaea5e8 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -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. */ +#include "IrrCompileConfig.h" #include "guiChatConsole.h" #include "chat.h" #include "client/client.h" @@ -618,6 +619,13 @@ bool GUIChatConsole::OnEvent(const SEvent& event) 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; } diff --git a/src/gui/guiChatConsole.h b/src/gui/guiChatConsole.h index 896342ab0..1152f2b2d 100644 --- a/src/gui/guiChatConsole.h +++ b/src/gui/guiChatConsole.h @@ -72,6 +72,8 @@ public: virtual void setVisible(bool visible); + virtual bool acceptsIME() { return true; } + private: void reformatConsole(); void recalculateConsolePosition(); diff --git a/src/gui/guiEditBox.cpp b/src/gui/guiEditBox.cpp index cd5a0868d..ba548aa2d 100644 --- a/src/gui/guiEditBox.cpp +++ b/src/gui/guiEditBox.cpp @@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "guiEditBox.h" +#include "IrrCompileConfig.h" #include "IGUISkin.h" #include "IGUIEnvironment.h" #include "IGUIFont.h" @@ -216,6 +217,11 @@ bool GUIEditBox::OnEvent(const SEvent &event) if (processMouse(event)) return true; break; +#if (IRRLICHT_VERSION_MT_REVISION >= 2) + case EET_STRING_INPUT_EVENT: + inputString(*event.StringInput.Str); + return true; +#endif default: break; } @@ -669,40 +675,45 @@ bool GUIEditBox::onKeyDelete(const SEvent &event, s32 &mark_begin, s32 &mark_end } 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) return; - if (c != 0) { - if (Text.size() < m_max || m_max == 0) { - core::stringw s; + u32 len = str.size(); + if (Text.size()+len <= m_max || m_max == 0) { + 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) { - // clang-format off - // 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; - - s = Text.subString(0, real_begin); - s.append(c); - s.append(Text.subString(real_end, Text.size() - real_end)); - Text = s; - m_cursor_pos = real_begin + 1; - // clang-format on - } else { - // 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); + s = Text.subString(0, real_begin); + s.append(str); + s.append(Text.subString(real_end, Text.size() - real_end)); + Text = s; + m_cursor_pos = real_begin + len; + } else { + // append string + s = Text.subString(0, m_cursor_pos); + s.append(str); + s.append(Text.subString(m_cursor_pos, + Text.size() - m_cursor_pos)); + Text = s; + m_cursor_pos += len; } + + m_blink_start_time = porting::getTimeMs(); + setTextMarkers(0, 0); } + breakText(); sendGuiEvent(EGET_EDITBOX_CHANGED); calculateScrollPos(); diff --git a/src/gui/guiEditBox.h b/src/gui/guiEditBox.h index c616d75d1..2a5c911bc 100644 --- a/src/gui/guiEditBox.h +++ b/src/gui/guiEditBox.h @@ -138,6 +138,8 @@ public: virtual void deserializeAttributes( io::IAttributes *in, io::SAttributeReadWriteOptions *options); + virtual bool acceptsIME() { return isEnabled() && m_writable; }; + protected: virtual void breakText() = 0; @@ -156,6 +158,7 @@ protected: virtual s32 getCursorPos(s32 x, s32 y) = 0; bool processKey(const SEvent &event); + virtual void inputString(const core::stringw &str); virtual void inputChar(wchar_t c); //! returns the line number that the cursor is on