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.
EET_APPLICATION_EVENT,
//! SDL text event
EET_SDL_TEXT_EVENT,
//! This enum is never used, it only forces the compiler to
//! compile these enumeration values to 32 bit.
EGUIET_FORCE_32_BIT = 0x7fffffff
@ -575,6 +578,15 @@ struct SEvent
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;
union
{
@ -590,6 +602,7 @@ struct SEvent
struct SUserEvent UserEvent;
struct SSystemEvent SystemEvent;
struct SApplicationEvent ApplicationEvent;
struct SSDLTextEvent SDLTextEvent;
};
};

View File

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

View File

@ -500,8 +500,6 @@ void CIrrDeviceSDL::createDriver()
// In input_manager.cpp
extern "C" void handle_joystick(SDL_Event& event);
// In CGUIEditBox.cpp
extern "C" void handle_textinput(SDL_Event& event);
// In main_loop.cpp
extern "C" void pause_mainloop();
extern "C" void resume_mainloop();
@ -742,10 +740,34 @@ bool CIrrDeviceSDL::run()
}
}
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:
handle_joystick(SDL_event);
handle_textinput(SDL_event);
break;
} // end switch

View File

@ -180,41 +180,6 @@ _raqm_get_grapheme_break (hb_codepoint_t ch,
};
#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
CGUIEditBox::CGUIEditBox(const wchar_t* text, bool border,
IGUIEnvironment* environment, IGUIElement* parent, s32 id,
@ -278,7 +243,6 @@ CGUIEditBox::~CGUIEditBox()
Android_toggleOnScreenKeyboard(false, 0, 0);
#elif defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
SDL_StopTextInput();
g_editbox = NULL;
#endif
#endif
@ -373,6 +337,26 @@ bool CGUIEditBox::OnEvent(const SEvent& event)
{
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:
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_)
SDL_StopTextInput();
g_editbox = NULL;
#endif
#ifdef ANDROID
// If using non touchscreen input in android dismiss text input
@ -419,7 +402,6 @@ bool CGUIEditBox::OnEvent(const SEvent& event)
calculateScrollPos();
#endif
SDL_StartTextInput();
g_editbox = this;
#endif
#if !defined(ANDROID) && !defined(WIN32)
calculateScrollPos();

View File

@ -140,9 +140,6 @@ namespace GUIEngine
virtual void setComposingText(const std::u32string& ct) { m_composing_text = ct; }
virtual void clearComposingText() { m_composing_text.clear(); }
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:
//! sets the area of the given line
void setTextRect(s32 line);