Browse Source

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.
yw05 3 years ago
parent
commit
85163b531f
4 changed files with 52 additions and 28 deletions
  1. 8 0
      src/gui/guiChatConsole.cpp
  2. 2 0
      src/gui/guiChatConsole.h
  3. 39 28
      src/gui/guiEditBox.cpp
  4. 3 0
      src/gui/guiEditBox.h

+ 8 - 0
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;
 }

+ 2 - 0
src/gui/guiChatConsole.h

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

+ 39 - 28
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;
 		}
@@ -670,39 +676,44 @@ bool GUIEditBox::onKeyDelete(const SEvent &event, s32 &mark_begin, s32 &mark_end
 
 void GUIEditBox::inputChar(wchar_t c)
 {
-	if (!isEnabled() || !m_writable)
+	if (c == 0)
 		return;
+	core::stringw s(&c, 1);
+	inputString(s);
+}
 
-	if (c != 0) {
-		if (Text.size() < m_max || m_max == 0) {
-			core::stringw s;
-
-			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;
-			}
+void GUIEditBox::inputString(const core::stringw &str)
+{
+	if (!isEnabled() || !m_writable)
+		return;
 
-			m_blink_start_time = porting::getTimeMs();
-			setTextMarkers(0, 0);
+	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;
+
+			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();

+ 3 - 0
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