Clean up input method code in windows with better unicode handling
This commit is contained in:
parent
c337976413
commit
7184119409
@ -61,14 +61,6 @@ namespace irr
|
|||||||
user receiver then no text will be sent to the console. */
|
user receiver then no text will be sent to the console. */
|
||||||
EET_LOG_TEXT_EVENT,
|
EET_LOG_TEXT_EVENT,
|
||||||
|
|
||||||
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
|
|
||||||
//! A input method event
|
|
||||||
/** Input method events are created by the input method message and passed to IrrlichtDevice::postEventFromUser.
|
|
||||||
Windows: Implemented.
|
|
||||||
Linux / Other: Not yet implemented. */
|
|
||||||
EET_IMPUT_METHOD_EVENT,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//! A user event with user data.
|
//! A user event with user data.
|
||||||
/** This is not used by Irrlicht and can be used to send user
|
/** This is not used by Irrlicht and can be used to send user
|
||||||
specific data though the system. The Irrlicht 'window handle'
|
specific data though the system. The Irrlicht 'window handle'
|
||||||
@ -167,20 +159,6 @@ namespace irr
|
|||||||
|
|
||||||
EMBSM_FORCE_32_BIT = 0x7fffffff
|
EMBSM_FORCE_32_BIT = 0x7fffffff
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
|
|
||||||
//! Enumeration for all input method events
|
|
||||||
enum EINPUT_METHOD_EVENT
|
|
||||||
{
|
|
||||||
//! a character from input method.
|
|
||||||
EIME_CHAR_INPUT = 0,
|
|
||||||
|
|
||||||
//! change position of composition window
|
|
||||||
EIME_CHANGE_POS,
|
|
||||||
|
|
||||||
EIME_FORCE_32_BIT = 0x7fffffff
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//! Enumeration for all touch input events
|
//! Enumeration for all touch input events
|
||||||
enum ETOUCH_INPUT_EVENT
|
enum ETOUCH_INPUT_EVENT
|
||||||
@ -590,21 +568,6 @@ struct SEvent
|
|||||||
EAPPLICATION_EVENT_TYPE EventType;
|
EAPPLICATION_EVENT_TYPE EventType;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
|
|
||||||
struct SInputMethodEvent
|
|
||||||
{
|
|
||||||
//! Parent window handle for IMM functions (Windows only)
|
|
||||||
void* Handle;
|
|
||||||
|
|
||||||
//! Character from Input Method
|
|
||||||
wchar_t Char;
|
|
||||||
|
|
||||||
//! Type of input method event
|
|
||||||
EINPUT_METHOD_EVENT Event;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
EEVENT_TYPE EventType;
|
EEVENT_TYPE EventType;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
@ -620,9 +583,6 @@ struct SEvent
|
|||||||
struct SUserEvent UserEvent;
|
struct SUserEvent UserEvent;
|
||||||
struct SSystemEvent SystemEvent;
|
struct SSystemEvent SystemEvent;
|
||||||
struct SApplicationEvent ApplicationEvent;
|
struct SApplicationEvent ApplicationEvent;
|
||||||
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
|
|
||||||
struct SInputMethodEvent InputMethodEvent;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -573,18 +573,6 @@ bool CGUIEnvironment::postEventFromUser(const SEvent& event)
|
|||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
|
|
||||||
case EET_IMPUT_METHOD_EVENT:
|
|
||||||
{
|
|
||||||
// todo : if CGUIEdit has not focus, close input method. Use WM_NOTIFY message.
|
|
||||||
if (Focus)
|
|
||||||
{
|
|
||||||
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
|
|
||||||
return Focus->OnEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
} // end switch
|
} // end switch
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
#include "utils/string_utils.hpp"
|
#include "utils/string_utils.hpp"
|
||||||
|
#include "utils/utf8.h"
|
||||||
|
|
||||||
#include "CTimer.h"
|
#include "CTimer.h"
|
||||||
#include "irrString.h"
|
#include "irrString.h"
|
||||||
@ -951,29 +952,6 @@ irr::CIrrDeviceWin32* getDeviceFromHWnd(HWND hWnd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace irr
|
|
||||||
{
|
|
||||||
void updateICPos(void* hWnd, s32 x, s32 y, s32 height)
|
|
||||||
{
|
|
||||||
COMPOSITIONFORM cf;
|
|
||||||
HWND hwnd = (HWND)hWnd;
|
|
||||||
HIMC hIMC = ImmGetContext(hwnd);
|
|
||||||
|
|
||||||
if(hIMC)
|
|
||||||
{
|
|
||||||
cf.dwStyle = CFS_POINT;
|
|
||||||
cf.ptCurrentPos.x = x;
|
|
||||||
cf.ptCurrentPos.y = y - height;
|
|
||||||
|
|
||||||
ImmSetCompositionWindow(hIMC, &cf);
|
|
||||||
|
|
||||||
ImmReleaseContext(hwnd, hIMC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // end of namespace irr
|
|
||||||
|
|
||||||
|
|
||||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
#ifndef WM_MOUSEWHEEL
|
#ifndef WM_MOUSEWHEEL
|
||||||
@ -1085,15 +1063,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m->irrMessage == irr::EMIE_LMOUSE_PRESSED_DOWN || m->irrMessage == irr::EMIE_LMOUSE_LEFT_UP)
|
|
||||||
{
|
|
||||||
event.EventType = irr::EET_IMPUT_METHOD_EVENT;
|
|
||||||
event.InputMethodEvent.Event = irr::EIME_CHANGE_POS;
|
|
||||||
event.InputMethodEvent.Handle = hWnd;
|
|
||||||
|
|
||||||
if (dev)
|
|
||||||
dev->postEventFromUser(event);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1112,25 +1081,16 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
case WM_IME_CHAR:
|
case WM_IME_CHAR:
|
||||||
{
|
{
|
||||||
event.EventType = irr::EET_IMPUT_METHOD_EVENT;
|
|
||||||
event.InputMethodEvent.Event = irr::EIME_CHAR_INPUT;
|
|
||||||
event.InputMethodEvent.Handle = hWnd;
|
|
||||||
|
|
||||||
event.KeyInput.Char = 0;
|
|
||||||
event.KeyInput.Key = irr::IRR_KEY_OEM_CLEAR;
|
|
||||||
event.KeyInput.Shift = 0;
|
|
||||||
event.KeyInput.Control = 0;
|
|
||||||
|
|
||||||
char bits[2] = { (char)((wParam & 0xff00) >> 8), (char)(wParam & 0xff) };
|
|
||||||
if (bits[0] == 0)
|
|
||||||
event.InputMethodEvent.Char = (wchar_t)wParam;
|
|
||||||
else
|
|
||||||
MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, bits, 2, &event.InputMethodEvent.Char, 1);
|
|
||||||
|
|
||||||
dev = getDeviceFromHWnd(hWnd);
|
dev = getDeviceFromHWnd(hWnd);
|
||||||
if (dev)
|
if (!dev)
|
||||||
dev->postEventFromUser(event);
|
return 0;
|
||||||
|
event.EventType = irr::EET_KEY_INPUT_EVENT;
|
||||||
|
event.KeyInput.PressedDown = true;
|
||||||
|
event.KeyInput.Char = (char32_t)wParam;
|
||||||
|
event.KeyInput.Key = irr::IRR_KEY_UNKNOWN;
|
||||||
|
event.KeyInput.Shift = false;
|
||||||
|
event.KeyInput.Control = false;
|
||||||
|
dev->postEventFromUser(event);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1169,41 +1129,29 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
event.KeyInput.Shift = ((allKeys[VK_SHIFT] & 0x80)!=0);
|
event.KeyInput.Shift = ((allKeys[VK_SHIFT] & 0x80)!=0);
|
||||||
event.KeyInput.Control = ((allKeys[VK_CONTROL] & 0x80)!=0);
|
event.KeyInput.Control = ((allKeys[VK_CONTROL] & 0x80)!=0);
|
||||||
|
event.KeyInput.Char = 0;
|
||||||
|
|
||||||
// Handle unicode and deadkeys in a way that works since Windows 95 and nt4.0
|
wchar_t keyChars[10] = {0};
|
||||||
// Using ToUnicode instead would be shorter, but would to my knowledge not run on 95 and 98.
|
|
||||||
WORD keyChars[2];
|
|
||||||
UINT scanCode = HIWORD(lParam);
|
UINT scanCode = HIWORD(lParam);
|
||||||
int conversionResult = ToAsciiEx(wParam,scanCode,allKeys,keyChars,0,KEYBOARD_INPUT_HKL);
|
int conversionResult = ToUnicodeEx((UINT)wParam,scanCode,allKeys,keyChars,_countof(keyChars),0,KEYBOARD_INPUT_HKL);
|
||||||
if (conversionResult == 1)
|
|
||||||
{
|
|
||||||
WORD unicodeChar;
|
|
||||||
MultiByteToWideChar(
|
|
||||||
KEYBOARD_INPUT_CODEPAGE,
|
|
||||||
MB_PRECOMPOSED, // default
|
|
||||||
(LPCSTR)keyChars,
|
|
||||||
sizeof(keyChars),
|
|
||||||
(WCHAR*)&unicodeChar,
|
|
||||||
1 );
|
|
||||||
event.KeyInput.Char = unicodeChar;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
event.KeyInput.Char = 0;
|
|
||||||
|
|
||||||
// allow composing characters like '@' with Alt Gr on non-US keyboards
|
// allow composing characters like '@' with Alt Gr on non-US keyboards
|
||||||
if ((allKeys[VK_MENU] & 0x80) != 0)
|
if ((allKeys[VK_MENU] & 0x80) != 0)
|
||||||
event.KeyInput.Control = 0;
|
event.KeyInput.Control = 0;
|
||||||
|
|
||||||
dev = getDeviceFromHWnd(hWnd);
|
dev = getDeviceFromHWnd(hWnd);
|
||||||
if (dev)
|
if (dev)
|
||||||
dev->postEventFromUser(event);
|
{
|
||||||
|
if (conversionResult >= 1)
|
||||||
event.EventType = irr::EET_IMPUT_METHOD_EVENT;
|
{
|
||||||
event.InputMethodEvent.Event = irr::EIME_CHANGE_POS;
|
for (int i = 0; i < conversionResult; i++)
|
||||||
event.InputMethodEvent.Handle = hWnd;
|
{
|
||||||
|
event.KeyInput.Char = keyChars[i];
|
||||||
if (dev)
|
dev->postEventFromUser(event);
|
||||||
dev->postEventFromUser(event);
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dev->postEventFromUser(event);
|
||||||
|
}
|
||||||
|
|
||||||
if (message == WM_SYSKEYDOWN || message == WM_SYSKEYUP)
|
if (message == WM_SYSKEYDOWN || message == WM_SYSKEYUP)
|
||||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
@ -1255,12 +1203,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
dev->switchToFullScreen();
|
dev->switchToFullScreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event.EventType = irr::EET_IMPUT_METHOD_EVENT;
|
|
||||||
event.InputMethodEvent.Event = irr::EIME_CHANGE_POS;
|
|
||||||
event.InputMethodEvent.Handle = hWnd;
|
|
||||||
|
|
||||||
if (dev)
|
|
||||||
dev->postEventFromUser(event);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_USER:
|
case WM_USER:
|
||||||
@ -1445,8 +1387,6 @@ CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params)
|
|||||||
// inform driver about the window size etc.
|
// inform driver about the window size etc.
|
||||||
resizeIfNecessary();
|
resizeIfNecessary();
|
||||||
|
|
||||||
// for reset the position of composition window
|
|
||||||
updateICPos(HWnd, 0, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -307,7 +307,7 @@ namespace irr
|
|||||||
//! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work.
|
//! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work.
|
||||||
virtual core::dimension2di getSupportedIconSize() const;
|
virtual core::dimension2di getSupportedIconSize() const;
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -386,6 +386,8 @@ namespace irr
|
|||||||
//! returns the win32 cursor control
|
//! returns the win32 cursor control
|
||||||
CCursorControl* getWin32CursorControl();
|
CCursorControl* getWin32CursorControl();
|
||||||
|
|
||||||
|
HWND getHandle() const { return HWnd; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//! create the driver
|
//! create the driver
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "guiengine/screen_keyboard.hpp"
|
#include "guiengine/screen_keyboard.hpp"
|
||||||
#include "utils/string_utils.hpp"
|
#include "utils/string_utils.hpp"
|
||||||
#include "utils/time.hpp"
|
#include "utils/time.hpp"
|
||||||
|
#include "utils/utf8.h"
|
||||||
|
|
||||||
#include "../../../lib/irrlicht/include/IrrCompileConfig.h"
|
#include "../../../lib/irrlicht/include/IrrCompileConfig.h"
|
||||||
#include "../../../lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h"
|
#include "../../../lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h"
|
||||||
@ -31,6 +32,10 @@
|
|||||||
#include "../../../lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.h"
|
#include "../../../lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
|
||||||
|
#include "../../../lib/irrlicht/source/Irrlicht/CIrrDeviceWin32.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
todo:
|
todo:
|
||||||
optional scrollbars
|
optional scrollbars
|
||||||
@ -172,13 +177,6 @@ _raqm_get_grapheme_break (hb_codepoint_t ch,
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
|
|
||||||
namespace irr
|
|
||||||
{
|
|
||||||
void updateICPos(void* hWnd, s32 x, s32 y, s32 height);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//! constructor
|
//! constructor
|
||||||
CGUIEditBox::CGUIEditBox(const wchar_t* text, bool border,
|
CGUIEditBox::CGUIEditBox(const wchar_t* text, bool border,
|
||||||
IGUIEnvironment* environment, IGUIElement* parent, s32 id,
|
IGUIEnvironment* environment, IGUIElement* parent, s32 id,
|
||||||
@ -396,12 +394,6 @@ bool CGUIEditBox::OnEvent(const SEvent& event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
|
|
||||||
case EET_IMPUT_METHOD_EVENT:
|
|
||||||
if (processIMEEvent(event))
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case EET_KEY_INPUT_EVENT:
|
case EET_KEY_INPUT_EVENT:
|
||||||
if (processKey(event))
|
if (processKey(event))
|
||||||
return true;
|
return true;
|
||||||
@ -852,7 +844,6 @@ bool CGUIEditBox::processKey(const SEvent& event)
|
|||||||
if (text_changed)
|
if (text_changed)
|
||||||
{
|
{
|
||||||
updateGlyphLayouts();
|
updateGlyphLayouts();
|
||||||
sendGuiEvent(EGET_EDITBOX_CHANGED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set new text markers
|
// Set new text markers
|
||||||
@ -871,38 +862,6 @@ bool CGUIEditBox::processKey(const SEvent& event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
|
|
||||||
bool CGUIEditBox::processIMEEvent(const SEvent& event)
|
|
||||||
{
|
|
||||||
switch(event.InputMethodEvent.Event)
|
|
||||||
{
|
|
||||||
case EIME_CHAR_INPUT:
|
|
||||||
inputChar(event.InputMethodEvent.Char);
|
|
||||||
return true;
|
|
||||||
case EIME_CHANGE_POS:
|
|
||||||
{
|
|
||||||
updateCursorDistance();
|
|
||||||
core::position2di pos = calculateICPos();
|
|
||||||
|
|
||||||
IGUIFont* font = OverrideFont;
|
|
||||||
IGUISkin* skin = Environment->getSkin();
|
|
||||||
|
|
||||||
if (!OverrideFont)
|
|
||||||
font = skin->getFont();
|
|
||||||
|
|
||||||
irr::updateICPos(event.InputMethodEvent.Handle, pos.X,pos.Y, font->getHeightPerLine());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) || defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
|
||||||
//! calculate the position of input composition window
|
//! calculate the position of input composition window
|
||||||
core::position2di CGUIEditBox::calculateICPos()
|
core::position2di CGUIEditBox::calculateICPos()
|
||||||
{
|
{
|
||||||
@ -914,7 +873,6 @@ core::position2di CGUIEditBox::calculateICPos()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
//! draws the element and its children
|
//! draws the element and its children
|
||||||
void CGUIEditBox::draw()
|
void CGUIEditBox::draw()
|
||||||
{
|
{
|
||||||
@ -922,6 +880,7 @@ void CGUIEditBox::draw()
|
|||||||
if (!IsVisible)
|
if (!IsVisible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
updateSurrogatePairText();
|
||||||
GUIEngine::ScreenKeyboard* screen_kbd = GUIEngine::ScreenKeyboard::getCurrent();
|
GUIEngine::ScreenKeyboard* screen_kbd = GUIEngine::ScreenKeyboard::getCurrent();
|
||||||
bool has_screen_kbd = (screen_kbd && screen_kbd->getEditBox() == this);
|
bool has_screen_kbd = (screen_kbd && screen_kbd->getEditBox() == this);
|
||||||
|
|
||||||
@ -1200,7 +1159,7 @@ s32 CGUIEditBox::getCursorPos(s32 x, s32 y)
|
|||||||
x += m_scroll_pos;
|
x += m_scroll_pos;
|
||||||
if (x < 0)
|
if (x < 0)
|
||||||
x = 0;
|
x = 0;
|
||||||
return getCurosrFromDimension(x, y, m_glyph_layouts, font->getHeightPerLine(),
|
return getCurosrFromDimension((f32)x, (f32)y, m_glyph_layouts, font->getHeightPerLine(),
|
||||||
font->getInverseShaping(), font->getScale());
|
font->getInverseShaping(), font->getScale());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1277,6 +1236,18 @@ void CGUIEditBox::inputChar(char32_t c)
|
|||||||
if (c < 32)
|
if (c < 32)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (c < 65536)
|
||||||
|
{
|
||||||
|
wchar_t wc = c & 65535;
|
||||||
|
if (utf8::internal::is_surrogate(wc) || !m_surrogate_chars.empty())
|
||||||
|
{
|
||||||
|
// Handle utf16 to 32 conversion together later, including any emoji
|
||||||
|
// joint character (which is not surrogate)
|
||||||
|
m_surrogate_chars.push_back(wc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((u32)getTextCount() < m_max_chars || m_max_chars == 0)
|
if ((u32)getTextCount() < m_max_chars || m_max_chars == 0)
|
||||||
{
|
{
|
||||||
std::u32string sub_str;
|
std::u32string sub_str;
|
||||||
@ -1306,7 +1277,6 @@ void CGUIEditBox::inputChar(char32_t c)
|
|||||||
m_force_show_cursor_time = StkTime::getMonoTimeMs() + 200;
|
m_force_show_cursor_time = StkTime::getMonoTimeMs() + 200;
|
||||||
updateGlyphLayouts();
|
updateGlyphLayouts();
|
||||||
setTextMarkers(0, 0);
|
setTextMarkers(0, 0);
|
||||||
sendGuiEvent(EGET_EDITBOX_CHANGED);
|
|
||||||
calculateScrollPos();
|
calculateScrollPos();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1368,6 +1338,7 @@ void CGUIEditBox::calculateScrollPos()
|
|||||||
m_scroll_pos = 0;
|
m_scroll_pos = 0;
|
||||||
|
|
||||||
// todo: adjust scrollbar
|
// todo: adjust scrollbar
|
||||||
|
core::position2di pos = calculateICPos();
|
||||||
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
||||||
if (irr_driver->getDevice()->getType() == irr::EIDT_X11)
|
if (irr_driver->getDevice()->getType() == irr::EIDT_X11)
|
||||||
{
|
{
|
||||||
@ -1375,10 +1346,29 @@ void CGUIEditBox::calculateScrollPos()
|
|||||||
irr_driver->getDevice());
|
irr_driver->getDevice());
|
||||||
if (dl)
|
if (dl)
|
||||||
{
|
{
|
||||||
dl->setIMELocation(calculateICPos());
|
dl->setIMELocation(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
|
||||||
|
CIrrDeviceWin32* win = NULL;
|
||||||
|
if (irr_driver->getDevice()->getType() == irr::EIDT_WIN32)
|
||||||
|
win = dynamic_cast<CIrrDeviceWin32*>(irr_driver->getDevice());
|
||||||
|
if (!win)
|
||||||
|
return;
|
||||||
|
|
||||||
|
COMPOSITIONFORM cf;
|
||||||
|
HIMC hIMC = ImmGetContext(win->getHandle());
|
||||||
|
|
||||||
|
if (hIMC)
|
||||||
|
{
|
||||||
|
cf.dwStyle = CFS_POINT;
|
||||||
|
cf.ptCurrentPos.x = pos.X;
|
||||||
|
cf.ptCurrentPos.y = pos.Y - font->getHeightPerLine();
|
||||||
|
ImmSetCompositionWindow(hIMC, &cf);
|
||||||
|
ImmReleaseContext(win->getHandle(), hIMC);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // SERVER_ONLY
|
#endif // SERVER_ONLY
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1436,7 +1426,7 @@ void CGUIEditBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWr
|
|||||||
out->addBool ("AutoScroll", AutoScroll);
|
out->addBool ("AutoScroll", AutoScroll);
|
||||||
out->addBool ("PasswordBox", PasswordBox);
|
out->addBool ("PasswordBox", PasswordBox);
|
||||||
core::stringw ch = L" ";
|
core::stringw ch = L" ";
|
||||||
ch[0] = PasswordChar;
|
ch[0] = (wchar_t)PasswordChar;
|
||||||
out->addString("PasswordChar", ch.c_str());
|
out->addString("PasswordChar", ch.c_str());
|
||||||
out->addEnum ("HTextAlign", HAlign, GUIAlignmentNames);
|
out->addEnum ("HTextAlign", HAlign, GUIAlignmentNames);
|
||||||
out->addEnum ("VTextAlign", VAlign, GUIAlignmentNames);
|
out->addEnum ("VTextAlign", VAlign, GUIAlignmentNames);
|
||||||
@ -1535,3 +1525,54 @@ void CGUIEditBox::updateGlyphLayouts()
|
|||||||
Text = StringUtils::utf32ToWide(m_edit_text);
|
Text = StringUtils::utf32ToWide(m_edit_text);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGUIEditBox::updateSurrogatePairText()
|
||||||
|
{
|
||||||
|
if (!m_surrogate_chars.empty())
|
||||||
|
{
|
||||||
|
wchar_t last_char = m_surrogate_chars.back();
|
||||||
|
if (utf8::internal::is_trail_surrogate(last_char) ||
|
||||||
|
!utf8::internal::is_surrogate(last_char))
|
||||||
|
{
|
||||||
|
const s32 realmbgn = m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end;
|
||||||
|
const s32 realmend = m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin;
|
||||||
|
m_surrogate_chars.push_back(0);
|
||||||
|
std::u32string result = StringUtils::wideToUtf32(m_surrogate_chars.data());
|
||||||
|
if (m_mark_begin == m_mark_end)
|
||||||
|
{
|
||||||
|
// insert text
|
||||||
|
std::u32string sub_str = m_edit_text.substr(0, m_cursor_pos);
|
||||||
|
sub_str += result;
|
||||||
|
sub_str += m_edit_text.substr(m_cursor_pos, m_edit_text.size() - m_cursor_pos);
|
||||||
|
|
||||||
|
if (m_max_chars == 0 || sub_str.size() <= m_max_chars) // thx to Fish FH for fix
|
||||||
|
{
|
||||||
|
m_edit_text = sub_str;
|
||||||
|
m_cursor_pos = m_cursor_pos + (s32)result.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// replace text
|
||||||
|
std::u32string sub_str = m_edit_text.substr(0, realmbgn);
|
||||||
|
sub_str += result;
|
||||||
|
sub_str += m_edit_text.substr(realmend, m_edit_text.size() - realmend);
|
||||||
|
|
||||||
|
if (m_max_chars == 0 || sub_str.size() <= m_max_chars) // thx to Fish FH for fix
|
||||||
|
{
|
||||||
|
m_edit_text = sub_str;
|
||||||
|
m_cursor_pos = realmbgn + (s32)sub_str.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_force_show_cursor_time = StkTime::getMonoTimeMs() + 200;
|
||||||
|
updateGlyphLayouts();
|
||||||
|
setTextMarkers(0, 0);
|
||||||
|
if (m_cursor_pos > getTextCount())
|
||||||
|
m_cursor_pos = getTextCount();
|
||||||
|
if (m_cursor_pos < 0)
|
||||||
|
m_cursor_pos = 0;
|
||||||
|
calculateScrollPos();
|
||||||
|
m_surrogate_chars.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -147,13 +147,8 @@ namespace GUIEngine
|
|||||||
void updateCursorDistance();
|
void updateCursorDistance();
|
||||||
bool processKey(const SEvent& event);
|
bool processKey(const SEvent& event);
|
||||||
bool processMouse(const SEvent& event);
|
bool processMouse(const SEvent& event);
|
||||||
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
|
|
||||||
bool processIMEEvent(const SEvent& event);
|
|
||||||
#endif
|
|
||||||
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) || defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
|
||||||
//! calculates the input composition position
|
//! calculates the input composition position
|
||||||
core::position2di calculateICPos();
|
core::position2di calculateICPos();
|
||||||
#endif
|
|
||||||
s32 getCursorPos(s32 x, s32 y);
|
s32 getCursorPos(s32 x, s32 y);
|
||||||
void updateGlyphLayouts();
|
void updateGlyphLayouts();
|
||||||
|
|
||||||
@ -192,7 +187,10 @@ namespace GUIEngine
|
|||||||
* windows */
|
* windows */
|
||||||
std::u32string m_edit_text;
|
std::u32string m_edit_text;
|
||||||
std::vector<GlyphLayout> m_glyph_layouts;
|
std::vector<GlyphLayout> m_glyph_layouts;
|
||||||
|
// Pre-edit surrogate chars
|
||||||
|
std::vector<wchar_t> m_surrogate_chars;
|
||||||
void correctCursor(s32& cursor_pos, bool left);
|
void correctCursor(s32& cursor_pos, bool left);
|
||||||
|
void updateSurrogatePairText();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user