Platform/SDL2: Refactor implementation

This commit is contained in:
Jérôme Leclercq 2021-12-01 10:42:01 +01:00
parent 45e5baf194
commit 97de5af838
2 changed files with 110 additions and 96 deletions

View File

@ -306,157 +306,171 @@ namespace Nz
}*/ }*/
} }
int SDLCALL WindowImpl::HandleEvent(void *userdata, SDL_Event* event) int WindowImpl::HandleEvent(void *userdata, SDL_Event* event)
{ {
try { try
auto window = static_cast<WindowImpl*>(userdata); {
WindowImpl* window = static_cast<WindowImpl*>(userdata);
WindowEvent evt;
evt.type = WindowEventType::Max;
switch (event->type) switch (event->type)
{ {
case SDL_WINDOWEVENT: case SDL_WINDOWEVENT:
{
if (SDL_GetWindowID(window->m_handle) != event->window.windowID) if (SDL_GetWindowID(window->m_handle) != event->window.windowID)
return 0; return 0;
WindowEvent windowEvent;
switch (event->window.event) switch (event->window.event)
{ {
case SDL_WINDOWEVENT_CLOSE: case SDL_WINDOWEVENT_CLOSE:
evt.type = WindowEventType::Quit; windowEvent.type = WindowEventType::Quit;
break; break;
case SDL_WINDOWEVENT_RESIZED: case SDL_WINDOWEVENT_RESIZED:
evt.type = WindowEventType::Resized; windowEvent.type = WindowEventType::Resized;
windowEvent.size.width = static_cast<unsigned int>(std::max(0, event->window.data1));
evt.size.width = static_cast<unsigned int>(std::max(0, event->window.data1)); windowEvent.size.height = static_cast<unsigned int>(std::max(0, event->window.data2));
evt.size.height = static_cast<unsigned int>(std::max(0, event->window.data2));
window->m_size.Set(evt.size.width, evt.size.height);
window->m_size.Set(windowEvent.size.width, windowEvent.size.height);
break; break;
case SDL_WINDOWEVENT_MOVED:
evt.type = WindowEventType::Moved;
evt.position.x = event->window.data1; case SDL_WINDOWEVENT_MOVED:
evt.position.y = event->window.data2; windowEvent.type = WindowEventType::Moved;
windowEvent.position.x = event->window.data1;
windowEvent.position.y = event->window.data2;
window->m_position.Set(event->window.data1, event->window.data2); window->m_position.Set(event->window.data1, event->window.data2);
break; break;
case SDL_WINDOWEVENT_FOCUS_GAINED: case SDL_WINDOWEVENT_FOCUS_GAINED:
evt.type = WindowEventType::GainedFocus; windowEvent.type = WindowEventType::GainedFocus;
window->RefreshCursor();
break; break;
case SDL_WINDOWEVENT_FOCUS_LOST: case SDL_WINDOWEVENT_FOCUS_LOST:
evt.type = WindowEventType::LostFocus; windowEvent.type = WindowEventType::LostFocus;
break; break;
case SDL_WINDOWEVENT_ENTER: case SDL_WINDOWEVENT_ENTER:
evt.type = WindowEventType::MouseEntered; windowEvent.type = WindowEventType::MouseEntered;
break; break;
case SDL_WINDOWEVENT_LEAVE:
evt.type = WindowEventType::MouseLeft;
case SDL_WINDOWEVENT_LEAVE:
windowEvent.type = WindowEventType::MouseLeft;
break; break;
} }
window->m_parent->PushEvent(windowEvent);
break; break;
}
case SDL_MOUSEMOTION: case SDL_MOUSEMOTION:
{
if (SDL_GetWindowID(window->m_handle) != event->motion.windowID) if (SDL_GetWindowID(window->m_handle) != event->motion.windowID)
return 0; return 0;
if (window->m_ignoreNextMouseMove /*&& event->motion.x == window->m_mousePos.x && event->motion.y == window->m_mousePos.y*/) if (window->m_ignoreNextMouseMove /*&& event->motion.x == window->m_mousePos.x && event->motion.y == window->m_mousePos.y*/)
{ {
window->m_ignoreNextMouseMove = false; window->m_ignoreNextMouseMove = false;
return 0; return 0;
} }
evt.type = WindowEventType::MouseMoved; WindowEvent windowEvent;
windowEvent.type = WindowEventType::MouseMoved;
evt.mouseMove.x = event->motion.x; windowEvent.mouseMove.x = event->motion.x;
evt.mouseMove.y = event->motion.y; windowEvent.mouseMove.y = event->motion.y;
evt.mouseMove.deltaX = event->motion.xrel; windowEvent.mouseMove.deltaX = event->motion.xrel;
evt.mouseMove.deltaY = event->motion.yrel; windowEvent.mouseMove.deltaY = event->motion.yrel;
window->m_parent->PushEvent(windowEvent);
break; break;
}
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
{
if (SDL_GetWindowID(window->m_handle) != event->button.windowID) if (SDL_GetWindowID(window->m_handle) != event->button.windowID)
return 0; return 0;
evt.mouseButton.button = SDLToNazaraButton(event->button.button); WindowEvent windowEvent;
evt.mouseButton.x = event->button.x; windowEvent.type = WindowEventType::MouseButtonPressed;
evt.mouseButton.y = event->button.y; windowEvent.mouseButton.button = SDLToNazaraButton(event->button.button);
evt.mouseButton.clickCount = event->button.clicks; windowEvent.mouseButton.x = event->button.x;
evt.type = WindowEventType::MouseButtonPressed; windowEvent.mouseButton.y = event->button.y;
windowEvent.mouseButton.clickCount = event->button.clicks;
window->m_parent->PushEvent(windowEvent);
break; break;
}
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
{
if (SDL_GetWindowID(window->m_handle) != event->button.windowID) if (SDL_GetWindowID(window->m_handle) != event->button.windowID)
return 0; return 0;
evt.mouseButton.button = SDLToNazaraButton(event->button.button); WindowEvent windowEvent;
evt.mouseButton.x = event->button.x; windowEvent.type = WindowEventType::MouseButtonReleased;
evt.mouseButton.y = event->button.y; windowEvent.mouseButton.button = SDLToNazaraButton(event->button.button);
windowEvent.mouseButton.x = event->button.x;
evt.type = WindowEventType::MouseButtonReleased; windowEvent.mouseButton.y = event->button.y;
window->m_parent->PushEvent(windowEvent);
break; break;
}
case SDL_MOUSEWHEEL: case SDL_MOUSEWHEEL:
{
if (SDL_GetWindowID(window->m_handle) != event->wheel.windowID) if (SDL_GetWindowID(window->m_handle) != event->wheel.windowID)
return 0; return 0;
evt.type = WindowEventType::MouseWheelMoved; WindowEvent windowEvent;
windowEvent.type = WindowEventType::MouseWheelMoved;
evt.mouseWheel.delta = event->wheel.y; windowEvent.mouseWheel.delta = event->wheel.y;
window->m_parent->PushEvent(windowEvent);
break; break;
}
case SDL_KEYDOWN: case SDL_KEYDOWN:
if (SDL_GetWindowID(window->m_handle) != event->key.windowID) if (SDL_GetWindowID(window->m_handle) != event->key.windowID)
return 0; return 0;
evt.type = WindowEventType::KeyPressed; WindowEvent windowEvent;
windowEvent.type = WindowEventType::KeyPressed;
windowEvent.key.alt = (event->key.keysym.mod & KMOD_ALT) != 0;
windowEvent.key.control = (event->key.keysym.mod & KMOD_CTRL) != 0;
windowEvent.key.repeated = event->key.repeat != 0;
windowEvent.key.scancode = SDLHelper::FromSDL(event->key.keysym.scancode);
windowEvent.key.shift = (event->key.keysym.mod & KMOD_SHIFT) != 0;
windowEvent.key.system = (event->key.keysym.mod & KMOD_GUI) != 0;
windowEvent.key.virtualKey = SDLHelper::FromSDL(event->key.keysym.sym);
evt.key.scancode = SDLHelper::FromSDL(event->key.keysym.scancode); window->m_parent->PushEvent(windowEvent);
evt.key.virtualKey = SDLHelper::FromSDL(event->key.keysym.sym);
evt.key.alt = (event->key.keysym.mod & KMOD_ALT) != 0;
evt.key.control = (event->key.keysym.mod & KMOD_CTRL) != 0;
evt.key.repeated = event->key.repeat != 0;
evt.key.shift = (event->key.keysym.mod & KMOD_SHIFT) != 0;
evt.key.system = (event->key.keysym.mod & KMOD_GUI) != 0;
// implements X11/Win32 APIs behavior for Enter and Backspace // implements X11/Win32 APIs behavior for Enter and Backspace
switch (evt.key.virtualKey) { switch (windowEvent.key.virtualKey)
{
case Nz::Keyboard::VKey::NumpadReturn: case Nz::Keyboard::VKey::NumpadReturn:
case Nz::Keyboard::VKey::Return: case Nz::Keyboard::VKey::Return:
{
if (window->m_lastEditEventLength != 0) if (window->m_lastEditEventLength != 0)
break; break;
window->m_parent->PushEvent(evt);
evt.type = WindowEventType::TextEntered; windowEvent.type = WindowEventType::TextEntered;
windowEvent.text.character = U'\n';
evt.text.character = U'\n'; windowEvent.text.repeated = event->key.repeat != 0;
evt.text.repeated = event->key.repeat != 0;
window->m_parent->PushEvent(evt);
window->m_parent->PushEvent(windowEvent);
break; break;
}
case Nz::Keyboard::VKey::Backspace: case Nz::Keyboard::VKey::Backspace:
window->m_parent->PushEvent(evt); windowEvent.type = WindowEventType::TextEntered;
windowEvent.text.character = U'\b';
evt.type = WindowEventType::TextEntered; windowEvent.text.repeated = event->key.repeat != 0;
evt.text.character = U'\b';
evt.text.repeated = event->key.repeat != 0;
window->m_parent->PushEvent(evt);
window->m_parent->PushEvent(windowEvent);
break; break;
default: default:
break; break;
} }
@ -464,67 +478,67 @@ namespace Nz
break; break;
case SDL_KEYUP: case SDL_KEYUP:
{
if (SDL_GetWindowID(window->m_handle) != event->key.windowID) if (SDL_GetWindowID(window->m_handle) != event->key.windowID)
return 0; return 0;
evt.type = WindowEventType::KeyReleased; windowEvent.type = WindowEventType::KeyReleased;
windowEvent.key.alt = (event->key.keysym.mod & KMOD_ALT) != 0;
evt.key.scancode = SDLHelper::FromSDL(event->key.keysym.scancode); windowEvent.key.control = (event->key.keysym.mod & KMOD_CTRL) != 0;
evt.key.virtualKey = SDLHelper::FromSDL(event->key.keysym.sym); windowEvent.key.repeated = event->key.repeat != 0;
evt.key.alt = (event->key.keysym.mod & KMOD_ALT) != 0; windowEvent.key.scancode = SDLHelper::FromSDL(event->key.keysym.scancode);
evt.key.control = (event->key.keysym.mod & KMOD_CTRL) != 0; windowEvent.key.shift = (event->key.keysym.mod & KMOD_SHIFT) != 0;
evt.key.repeated = event->key.repeat != 0; windowEvent.key.system = (event->key.keysym.mod & KMOD_GUI) != 0;
evt.key.shift = (event->key.keysym.mod & KMOD_SHIFT) != 0; windowEvent.key.virtualKey = SDLHelper::FromSDL(event->key.keysym.sym);
evt.key.system = (event->key.keysym.mod & KMOD_GUI) != 0;
window->m_parent->PushEvent(windowEvent);
break; break;
}
case SDL_TEXTINPUT: case SDL_TEXTINPUT:
{ {
if (SDL_GetWindowID(window->m_handle) != event->text.windowID) if (SDL_GetWindowID(window->m_handle) != event->text.windowID)
return 0; return 0;
evt.type = WindowEventType::TextEntered; windowEvent.type = WindowEventType::TextEntered;
evt.text.repeated = false; windowEvent.text.repeated = false;
utf8::unchecked::iterator<const char*> it(event->text.text); utf8::unchecked::iterator<const char*> it(event->text.text);
do do
{ {
evt.text.character = *it; windowEvent.text.character = *it;
window->m_parent->PushEvent(evt); window->m_parent->PushEvent(windowEvent);
} while (*it++); }
while (*it++);
// prevent post switch event
evt.type = WindowEventType::Max;
break; break;
} }
case SDL_TEXTEDITING: case SDL_TEXTEDITING:
{
if (SDL_GetWindowID(window->m_handle) != event->edit.windowID) if (SDL_GetWindowID(window->m_handle) != event->edit.windowID)
return 0; return 0;
evt.type = WindowEventType::TextEdited; windowEvent.type = WindowEventType::TextEdited;
evt.edit.length = event->edit.length; windowEvent.edit.length = event->edit.length;
window->m_lastEditEventLength = evt.edit.length; window->m_lastEditEventLength = windowEvent.edit.length;
for (std::size_t i = 0; i < 32; i++) for (std::size_t i = 0; i < 32; i++)
{ {
evt.edit.text[i] = event->edit.text[i]; windowEvent.edit.text[i] = event->edit.text[i];
} }
window->m_parent->PushEvent(windowEvent);
break; break;
} }
}
if (evt.type != WindowEventType::Max)
window->m_parent->PushEvent(evt);
} }
catch (std::exception e) catch (std::exception e)
{ {
NazaraError(e.what()); NazaraError(e.what());
} }
catch (...) // Don't let any exceptions go thru C calls catch (...) // Don't let any exceptions go through C calls
{ {
NazaraError("An unknown error happened"); NazaraError("An unknown error happened");
} }

View File

@ -79,7 +79,7 @@ namespace Nz
static void Uninitialize(); static void Uninitialize();
private: private:
int static SDLCALL HandleEvent(void *userdata, SDL_Event * event); static int SDLCALL HandleEvent(void* userdata, SDL_Event* event);
void PrepareWindow(bool fullscreen); void PrepareWindow(bool fullscreen);