]> git.lizzy.rs Git - irrlicht.git/commitdiff
Prepare GUI for IME support
authoryw05 <37980625+yw05@users.noreply.github.com>
Tue, 30 Mar 2021 11:52:45 +0000 (13:52 +0200)
committersfan5 <sfan5@live.de>
Fri, 2 Apr 2021 21:17:27 +0000 (23:17 +0200)
include/IEventReceiver.h
include/IGUIElement.h
source/Irrlicht/CGUIEditBox.cpp
source/Irrlicht/CGUIEditBox.h
source/Irrlicht/CGUIEnvironment.cpp
source/Irrlicht/CIrrDeviceStub.cpp
source/Irrlicht/CIrrDeviceStub.h

index e1c78a623e9a5f43d061d0de226e58366da6297d..4b0af179372ec09e4d68e55ca4af7b08f07146e3 100644 (file)
@@ -34,7 +34,11 @@ namespace irr
                IrrlichtDevice::postEventFromUser. They take the same path as mouse events. */\r
                EET_KEY_INPUT_EVENT,\r
 \r
-        //! A touch input event.\r
+               //! A string input event.\r
+               /** This event is created when multiple characters are sent at a time (e.g. using an IME). */\r
+               EET_STRING_INPUT_EVENT,\r
+\r
+               //! A touch input event.\r
                EET_TOUCH_INPUT_EVENT,\r
 \r
                //! A accelerometer event.\r
@@ -413,7 +417,14 @@ struct SEvent
                bool Control:1;\r
        };\r
 \r
-    //! Any kind of touch event.\r
+       //! String input event.\r
+       struct SStringInput\r
+       {\r
+               //! The string that is entered\r
+               core::stringw *Str;\r
+       };\r
+\r
+       //! Any kind of touch event.\r
        struct STouchInput\r
        {\r
                // Touch ID.\r
@@ -581,6 +592,7 @@ struct SEvent
                struct SGUIEvent GUIEvent;\r
                struct SMouseInput MouseInput;\r
                struct SKeyInput KeyInput;\r
+               struct SStringInput StringInput;\r
                struct STouchInput TouchInput;\r
                struct SAccelerometerEvent AccelerometerEvent;\r
                struct SGyroscopeEvent GyroscopeEvent;\r
index 5968430ab95b4384e1953c4042986d1336673f71..c6f275b12af70c5fde40ae5093ab3e24248d8c04 100644 (file)
@@ -789,6 +789,13 @@ public:
        }\r
 \r
 \r
+       //! Returns whether the element takes input from the IME\r
+       virtual bool acceptsIME()\r
+       {\r
+               return false;\r
+       }\r
+\r
+\r
        //! Writes attributes of the scene node.\r
        /** Implement this to expose the attributes of your scene node for\r
        scripting languages, editors, debuggers or xml serialization purposes. */\r
index a55664e1aa2f7098a54cce4b6b8a1adefb064392..5d25601ac1173d1c43749767d7a6f3a47c606db3 100644 (file)
@@ -252,6 +252,10 @@ bool CGUIEditBox::OnEvent(const SEvent& event)
                        if (processMouse(event))\r
                                return true;\r
                        break;\r
+               case EET_STRING_INPUT_EVENT:\r
+                       inputString(*event.StringInput.Str);\r
+                       return true;\r
+                       break;\r
                default:\r
                        break;\r
                }\r
@@ -1391,76 +1395,91 @@ s32 CGUIEditBox::getLineFromPos(s32 pos)
 \r
 \r
 void CGUIEditBox::inputChar(wchar_t c)\r
+{\r
+       if (c == 0)\r
+               return;\r
+       core::stringw s(&c, 1);\r
+       inputString(s);\r
+}\r
+\r
+void CGUIEditBox::inputString(const core::stringw &str)\r
 {\r
        if (!isEnabled())\r
                return;\r
 \r
-       if (c != 0)\r
+       core::stringw s;\r
+       u32 len = str.size();\r
+\r
+       if (MarkBegin != MarkEnd)\r
        {\r
-               {\r
-                       core::stringw s;\r
+               // replace marked text\r
+               const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd;\r
+               const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;\r
 \r
-                       if (MarkBegin != MarkEnd)\r
+               s = Text.subString(0, realmbgn);\r
+               s.append(str);\r
+               s.append( Text.subString(realmend, Text.size()-realmend) );\r
+               Text = s;\r
+               CursorPos = realmbgn+len;\r
+       }\r
+       else if ( OverwriteMode )\r
+       {\r
+               //check to see if we are at the end of the text\r
+               if ( (u32)CursorPos+len < Text.size())\r
+               {\r
+                       bool isEOL = false;\r
+                       s32 EOLPos;\r
+                       for (u32 i = CursorPos; i < CursorPos+len && i < Max; i++)\r
                        {\r
-                               // replace marked text\r
-                               const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd;\r
-                               const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;\r
-\r
-                               s = Text.subString(0, realmbgn);\r
-                               s.append(c);\r
-                               s.append( Text.subString(realmend, Text.size()-realmend) );\r
-                               Text = s;\r
-                               CursorPos = realmbgn+1;\r
+                               if (Text[i] == L'\n' || Text[i] == L'\r')\r
+                               {\r
+                                       isEOL = true;\r
+                                       EOLPos = i;\r
+                                       break;\r
+                               }\r
                        }\r
-                       else if ( OverwriteMode )\r
+                       if (!isEOL || Text.size()+len <= Max || Max == 0)\r
                        {\r
-                               //check to see if we are at the end of the text\r
-                               if ( (u32)CursorPos != Text.size())\r
+                               s = Text.subString(0, CursorPos);\r
+                               s.append(str);\r
+                               if ( isEOL )\r
                                {\r
-                                       bool isEOL = (Text[CursorPos] == L'\n' ||Text[CursorPos] == L'\r' );\r
-                                       if (!isEOL || Text.size() < Max || Max == 0)\r
-                                       {\r
-                                               s = Text.subString(0, CursorPos);\r
-                                               s.append(c);\r
-                                               if ( isEOL )\r
-                                               {\r
-                                                       //just keep appending to the current line\r
-                                                       //This follows the behavior of other gui libraries behaviors\r
-                                                       s.append( Text.subString(CursorPos, Text.size()-CursorPos) );\r
-                                               }\r
-                                               else\r
-                                               {\r
-                                                       //replace the next character\r
-                                                       s.append( Text.subString(CursorPos + 1,Text.size() - CursorPos + 1));\r
-                                               }\r
-                                               Text = s;\r
-                                               ++CursorPos;\r
-                                       }\r
+                                       //just keep appending to the current line\r
+                                       //This follows the behavior of other gui libraries behaviors\r
+                                       s.append( Text.subString(EOLPos, Text.size()-EOLPos) );\r
                                }\r
-                               else if (Text.size() < Max || Max == 0)\r
+                               else\r
                                {\r
-                                       // add new character because we are at the end of the string\r
-                                       s = Text.subString(0, CursorPos);\r
-                                       s.append(c);\r
-                                       s.append( Text.subString(CursorPos, Text.size()-CursorPos) );\r
-                                       Text = s;\r
-                                       ++CursorPos;\r
+                                       //replace the next character\r
+                                       s.append( Text.subString(CursorPos + len,Text.size() - CursorPos - len));\r
                                }\r
-                       }\r
-                       else if (Text.size() < Max || Max == 0)\r
-                       {\r
-                               // add new character\r
-                               s = Text.subString(0, CursorPos);\r
-                               s.append(c);\r
-                               s.append( Text.subString(CursorPos, Text.size()-CursorPos) );\r
                                Text = s;\r
-                               ++CursorPos;\r
+                               CursorPos+=len;\r
                        }\r
-\r
-                       BlinkStartTime = os::Timer::getTime();\r
-                       setTextMarkers(0, 0);\r
                }\r
+               else if (Text.size()+len <= Max || Max == 0)\r
+               {\r
+                       // add new character because we are at the end of the string\r
+                       s = Text.subString(0, CursorPos);\r
+                       s.append(str);\r
+                       s.append( Text.subString(CursorPos+len, Text.size()-CursorPos-len) );\r
+                       Text = s;\r
+                       CursorPos+=len;\r
+               }\r
+       }\r
+       else if (Text.size()+len <= Max || Max == 0)\r
+       {\r
+               // add new character\r
+               s = Text.subString(0, CursorPos);\r
+               s.append(str);\r
+               s.append( Text.subString(CursorPos, Text.size()-CursorPos) );\r
+               Text = s;\r
+               CursorPos+=len;\r
        }\r
+\r
+       BlinkStartTime = os::Timer::getTime();\r
+       setTextMarkers(0, 0);\r
+\r
        breakText();\r
        calculateScrollPos();\r
        sendGuiEvent(EGET_EDITBOX_CHANGED);\r
@@ -1625,6 +1644,12 @@ void CGUIEditBox::sendGuiEvent(EGUI_EVENT_TYPE type)
        }\r
 }\r
 \r
+//! Returns whether the element takes input from the IME\r
+bool CGUIEditBox::acceptsIME()\r
+{\r
+       return isEnabled();\r
+}\r
+\r
 //! Writes attributes of the element.\r
 void CGUIEditBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const\r
 {\r
index f251e5ec95fe23885eb7d07b1bb1d9cf5ae0ab4a..4943567266747f1a5c3edc46d2d4e701a511ef26 100644 (file)
@@ -139,6 +139,10 @@ namespace gui
                //! Updates the absolute position, splits text if required\r
                virtual void updateAbsolutePosition() _IRR_OVERRIDE_;\r
 \r
+               //! Returns whether the element takes input from the IME\r
+               virtual bool acceptsIME() _IRR_OVERRIDE_;\r
+\r
+\r
                //! Writes attributes of the element.\r
                virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const _IRR_OVERRIDE_;\r
 \r
@@ -154,6 +158,8 @@ namespace gui
                s32 getLineFromPos(s32 pos);\r
                //! adds a letter to the edit box\r
                void inputChar(wchar_t c);\r
+               //! adds a string to the edit box\r
+               void inputString(const core::stringw &str);\r
                //! calculates the current scroll position\r
                void calculateScrollPos();\r
                //! calculated the FrameRect\r
index e970d64061c6989028e9e16cdd01c4f7310ff11e..6a04b1e31f652f26a17ae4347a17b8ec14b67cbe 100644 (file)
@@ -656,6 +656,10 @@ bool CGUIEnvironment::postEventFromUser(const SEvent& event)
                        }\r
                }\r
                break;\r
+       case EET_STRING_INPUT_EVENT:\r
+               if (Focus && Focus->OnEvent(event))\r
+                       return true;\r
+               break;\r
        default:\r
                break;\r
        } // end switch\r
index 0ecf128ebde00fec09ffd415f2dd281da8f9e112..31e21ab77a85b29b713c82ed21a498128dc663b9 100644 (file)
@@ -6,6 +6,7 @@
 #include "ISceneManager.h"\r
 #include "IEventReceiver.h"\r
 #include "IFileSystem.h"\r
+#include "IGUIElement.h"\r
 #include "IGUIEnvironment.h"\r
 #include "os.h"\r
 #include "IrrCompileConfig.h"\r
@@ -503,6 +504,14 @@ void CIrrDeviceStub::clearSystemMessages()
 {\r
 }\r
 \r
+//! Checks whether the input device should take input from the IME\r
+bool CIrrDeviceStub::acceptsIME()\r
+{\r
+       if (!GUIEnvironment)\r
+               return false;\r
+       gui::IGUIElement *elem = GUIEnvironment->getFocus();\r
+       return elem && elem->acceptsIME();\r
+}\r
 \r
 \r
 } // end namespace irr\r
index 367faf1355dde6d0683db195ece3458e1a2a05fc..7ea05bc58e05d3b58bf2621ef7c9fcab0dd68db3 100644 (file)
@@ -194,6 +194,9 @@ namespace irr
                void calculateGammaRamp ( u16 *ramp, f32 gamma, f32 relativebrightness, f32 relativecontrast );\r
                void calculateGammaFromRamp ( f32 &gamma, const u16 *ramp );\r
 \r
+               //! Checks whether the input device should take input from the IME\r
+               bool acceptsIME();\r
+\r
                video::IVideoDriver* VideoDriver;\r
                gui::IGUIEnvironment* GUIEnvironment;\r
                scene::ISceneManager* SceneManager;\r