Fix in game chat dialog crash

This commit is contained in:
Benau 2020-07-15 15:56:53 +08:00
parent dc8e4ba0dc
commit 3a62d5179e
5 changed files with 60 additions and 45 deletions

View File

@ -82,6 +82,9 @@ namespace irr
//! Application state events like a resume, pause etc. //! Application state events like a resume, pause etc.
EET_APPLICATION_EVENT, EET_APPLICATION_EVENT,
//! SDL text event
EET_SDL_TEXT_EVENT,
//! This enum is never used, it only forces the compiler to //! This enum is never used, it only forces the compiler to
//! compile these enumeration values to 32 bit. //! compile these enumeration values to 32 bit.
EGUIET_FORCE_32_BIT = 0x7fffffff EGUIET_FORCE_32_BIT = 0x7fffffff
@ -575,6 +578,15 @@ struct SEvent
EAPPLICATION_EVENT_TYPE EventType; EAPPLICATION_EVENT_TYPE EventType;
}; };
// Application state event
struct SSDLTextEvent
{
u32 Type; // SDL_TEXTEDITING or SDL_TEXTINPUT
c8 Text[32];
s32 Start; // SDL_TEXTEDITING usage
s32 Length; // SDL_TEXTEDITING usage
};
EEVENT_TYPE EventType; EEVENT_TYPE EventType;
union union
{ {
@ -590,6 +602,7 @@ struct SEvent
struct SUserEvent UserEvent; struct SUserEvent UserEvent;
struct SSystemEvent SystemEvent; struct SSystemEvent SystemEvent;
struct SApplicationEvent ApplicationEvent; struct SApplicationEvent ApplicationEvent;
struct SSDLTextEvent SDLTextEvent;
}; };
}; };

View File

@ -553,6 +553,7 @@ bool CGUIEnvironment::postEventFromUser(const SEvent& event)
break; break;
case EET_KEY_INPUT_EVENT: case EET_KEY_INPUT_EVENT:
case EET_SDL_TEXT_EVENT:
{ {
if (Focus && Focus->OnEvent(event)) if (Focus && Focus->OnEvent(event))
return true; return true;

View File

@ -500,8 +500,6 @@ void CIrrDeviceSDL::createDriver()
// In input_manager.cpp // In input_manager.cpp
extern "C" void handle_joystick(SDL_Event& event); extern "C" void handle_joystick(SDL_Event& event);
// In CGUIEditBox.cpp
extern "C" void handle_textinput(SDL_Event& event);
// In main_loop.cpp // In main_loop.cpp
extern "C" void pause_mainloop(); extern "C" void pause_mainloop();
extern "C" void resume_mainloop(); extern "C" void resume_mainloop();
@ -742,10 +740,34 @@ bool CIrrDeviceSDL::run()
} }
} }
break; break;
case SDL_TEXTEDITING:
{
irrevent.EventType = irr::EET_SDL_TEXT_EVENT;
irrevent.SDLTextEvent.Type = SDL_event.type;
const size_t size = sizeof(irrevent.SDLTextEvent.Text);
const size_t other_size = sizeof(SDL_event.edit.text);
static_assert(sizeof(size) == sizeof(other_size), "Wrong size");
memcpy(irrevent.SDLTextEvent.Text, SDL_event.edit.text, size);
irrevent.SDLTextEvent.Start = SDL_event.edit.start;
irrevent.SDLTextEvent.Length = SDL_event.edit.length;
postEventFromUser(irrevent);
}
break;
case SDL_TEXTINPUT:
{
irrevent.EventType = irr::EET_SDL_TEXT_EVENT;
irrevent.SDLTextEvent.Type = SDL_event.type;
const size_t size = sizeof(irrevent.SDLTextEvent.Text);
const size_t other_size = sizeof(SDL_event.text.text);
static_assert(sizeof(size) == sizeof(other_size), "Wrong size");
memcpy(irrevent.SDLTextEvent.Text, SDL_event.text.text, size);
irrevent.SDLTextEvent.Start = 0;
irrevent.SDLTextEvent.Length = 0;
postEventFromUser(irrevent);
}
break;
default: default:
handle_joystick(SDL_event); handle_joystick(SDL_event);
handle_textinput(SDL_event);
break; break;
} // end switch } // end switch

View File

@ -180,41 +180,6 @@ _raqm_get_grapheme_break (hb_codepoint_t ch,
}; };
#endif #endif
#if !defined(SERVER_ONLY) && defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
CGUIEditBox* g_editbox = NULL;
extern "C" void handle_textinput(SDL_Event& event)
{
if (g_editbox)
g_editbox->handleSDLEvent(event);
}
void CGUIEditBox::handleSDLEvent(SDL_Event& event)
{
switch (event.type)
{
case SDL_TEXTINPUT:
{
m_composing_text.clear();
m_composing_start = 0;
m_composing_end = 0;
std::u32string text = StringUtils::utf8ToUtf32(event.text.text);
for (char32_t t : text)
inputChar(t);
break;
}
case SDL_TEXTEDITING:
m_composing_text = StringUtils::utf8ToUtf32(event.edit.text);
m_composing_start = m_cursor_pos;
m_composing_end = m_cursor_pos + m_composing_text.size();
// In linux these values don't seem to provide any more useful info
// It's always 0, event.edit.text.size()
//printf("Debug: %d, %d\n", event.edit.start, event.edit.length);
break;
}
}
#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,
@ -278,7 +243,6 @@ CGUIEditBox::~CGUIEditBox()
Android_toggleOnScreenKeyboard(false, 0, 0); Android_toggleOnScreenKeyboard(false, 0, 0);
#elif defined(_IRR_COMPILE_WITH_SDL_DEVICE_) #elif defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
SDL_StopTextInput(); SDL_StopTextInput();
g_editbox = NULL;
#endif #endif
#endif #endif
@ -373,6 +337,26 @@ bool CGUIEditBox::OnEvent(const SEvent& event)
{ {
switch(event.EventType) switch(event.EventType)
{ {
case EET_SDL_TEXT_EVENT:
if (event.SDLTextEvent.Type == SDL_TEXTINPUT)
{
m_composing_text.clear();
m_composing_start = 0;
m_composing_end = 0;
std::u32string text = StringUtils::utf8ToUtf32(event.SDLTextEvent.Text);
for (char32_t t : text)
inputChar(t);
}
else
{
m_composing_text = StringUtils::utf8ToUtf32(event.SDLTextEvent.Text);
m_composing_start = m_cursor_pos;
m_composing_end = m_cursor_pos + m_composing_text.size();
// In linux these values don't seem to provide any more useful info
// It's always 0, event.edit.text.size()
//printf("Debug: %d, %d\n", event.SDLTextEvent.Start, event.SDLTextEvent.Length);
}
return true;
case EET_GUI_EVENT: case EET_GUI_EVENT:
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
{ {
@ -383,7 +367,6 @@ bool CGUIEditBox::OnEvent(const SEvent& event)
} }
#if !defined(ANDROID) && defined(_IRR_COMPILE_WITH_SDL_DEVICE_) #if !defined(ANDROID) && defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
SDL_StopTextInput(); SDL_StopTextInput();
g_editbox = NULL;
#endif #endif
#ifdef ANDROID #ifdef ANDROID
// If using non touchscreen input in android dismiss text input // If using non touchscreen input in android dismiss text input
@ -419,7 +402,6 @@ bool CGUIEditBox::OnEvent(const SEvent& event)
calculateScrollPos(); calculateScrollPos();
#endif #endif
SDL_StartTextInput(); SDL_StartTextInput();
g_editbox = this;
#endif #endif
#if !defined(ANDROID) && !defined(WIN32) #if !defined(ANDROID) && !defined(WIN32)
calculateScrollPos(); calculateScrollPos();

View File

@ -140,9 +140,6 @@ namespace GUIEngine
virtual void setComposingText(const std::u32string& ct) { m_composing_text = ct; } virtual void setComposingText(const std::u32string& ct) { m_composing_text = ct; }
virtual void clearComposingText() { m_composing_text.clear(); } virtual void clearComposingText() { m_composing_text.clear(); }
virtual const core::position2di& getICPos() const { return m_ic_pos; } virtual const core::position2di& getICPos() const { return m_ic_pos; }
#if !defined(SERVER_ONLY) && defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
void handleSDLEvent(SDL_Event& event);
#endif
protected: protected:
//! sets the area of the given line //! sets the area of the given line
void setTextRect(s32 line); void setTextRect(s32 line);