diff --git a/Widgets/Event.h b/Widgets/Event.h index a6f5742c34..7178753e9b 100644 --- a/Widgets/Event.h +++ b/Widgets/Event.h @@ -135,7 +135,7 @@ public: String text() const { return m_text; } private: - friend class EventLoopSDL; + friend class EventLoop; int m_key { 0 }; bool m_ctrl { false }; bool m_alt { false }; diff --git a/Widgets/EventLoop.cpp b/Widgets/EventLoop.cpp index 5c4d5b7ec7..1645eec5e5 100644 --- a/Widgets/EventLoop.cpp +++ b/Widgets/EventLoop.cpp @@ -1,6 +1,7 @@ #include "EventLoop.h" #include "Event.h" #include "Object.h" +#include "WindowManager.h" static EventLoop* s_mainEventLoop; @@ -50,3 +51,108 @@ void EventLoop::postEvent(Object* receiver, OwnPtr&& event) m_queuedEvents.append({ receiver, std::move(event) }); } +#ifdef USE_SDL +static inline MouseButton toMouseButton(byte sdlButton) +{ + if (sdlButton == 1) + return MouseButton::Left; + if (sdlButton == 2) + return MouseButton::Middle; + if (sdlButton == 3) + return MouseButton::Right; + ASSERT_NOT_REACHED(); + return MouseButton::None; +} + +void EventLoop::handleKeyEvent(Event::Type type, const SDL_KeyboardEvent& sdlKey) +{ + auto keyEvent = make(type, 0); + int key = 0; + + switch (sdlKey.keysym.sym) { + case SDLK_LEFT: key = KeyboardKey::LeftArrow; break; + case SDLK_RIGHT: key = KeyboardKey::RightArrow; break; + case SDLK_UP: key = KeyboardKey::UpArrow; break; + case SDLK_DOWN: key = KeyboardKey::DownArrow; break; + case SDLK_BACKSPACE: key = KeyboardKey::Backspace; break; + case SDLK_RETURN: key = KeyboardKey::Return; break; + } + keyEvent->m_key = key; + + if (sdlKey.keysym.sym > SDLK_UNKNOWN && sdlKey.keysym.sym <= 'z') { + char buf[] = { 0, 0 }; + char& ch = buf[0]; + ch = (char)sdlKey.keysym.sym; + if (sdlKey.keysym.mod & KMOD_SHIFT) { + if (ch >= 'a' && ch <= 'z') { + ch &= ~0x20; + } else { + switch (ch) { + case '1': ch = '!'; break; + case '2': ch = '@'; break; + case '3': ch = '#'; break; + case '4': ch = '$'; break; + case '5': ch = '%'; break; + case '6': ch = '^'; break; + case '7': ch = '&'; break; + case '8': ch = '*'; break; + case '9': ch = '('; break; + case '0': ch = ')'; break; + case '-': ch = '_'; break; + case '=': ch = '+'; break; + case '`': ch = '~'; break; + case ',': ch = '<'; break; + case '.': ch = '>'; break; + case '/': ch = '?'; break; + case '[': ch = '{'; break; + case ']': ch = '}'; break; + case '\\': ch = '|'; break; + case '\'': ch = '"'; break; + case ';': ch = ':'; break; + } + } + } + keyEvent->m_text = buf; + } + + keyEvent->m_shift = sdlKey.keysym.mod & KMOD_SHIFT; + keyEvent->m_ctrl = sdlKey.keysym.mod & KMOD_CTRL; + keyEvent->m_alt = sdlKey.keysym.mod & KMOD_ALT; + + postEvent(&WindowManager::the(), std::move(keyEvent)); +} + +void EventLoop::waitForEvent() +{ + SDL_Event sdlEvent; + while (SDL_PollEvent(&sdlEvent) != 0) { + switch (sdlEvent.type) { + case SDL_QUIT: + postEvent(nullptr, make()); + return; + case SDL_WINDOWEVENT: + if (sdlEvent.window.event == SDL_WINDOWEVENT_EXPOSED) { + // Spam paint events whenever we get exposed. + // This is obviously not ideal, but the SDL backend here is just a prototype anyway. + postEvent(&WindowManager::the(), make()); + } + return; + case SDL_MOUSEMOTION: + postEvent(&WindowManager::the(), make(Event::MouseMove, sdlEvent.motion.x, sdlEvent.motion.y)); + return; + case SDL_MOUSEBUTTONDOWN: + postEvent(&WindowManager::the(), make(Event::MouseDown, sdlEvent.button.x, sdlEvent.button.y, toMouseButton(sdlEvent.button.button))); + return; + case SDL_MOUSEBUTTONUP: + postEvent(&WindowManager::the(), make(Event::MouseUp, sdlEvent.button.x, sdlEvent.button.y, toMouseButton(sdlEvent.button.button))); + return; + case SDL_KEYDOWN: + handleKeyEvent(Event::KeyDown, sdlEvent.key); + return; + case SDL_KEYUP: + handleKeyEvent(Event::KeyUp, sdlEvent.key); + return; + } + } +} +#endif diff --git a/Widgets/EventLoop.h b/Widgets/EventLoop.h index ca8b912bc0..9b112ab59b 100644 --- a/Widgets/EventLoop.h +++ b/Widgets/EventLoop.h @@ -1,27 +1,33 @@ #pragma once +#include "Event.h" #include #include -class Event; +#ifdef USE_SDL +#include +#endif + class Object; class EventLoop { public: - virtual ~EventLoop(); + EventLoop(); + ~EventLoop(); int exec(); - virtual void waitForEvent() = 0; - void postEvent(Object* receiver, OwnPtr&&); static EventLoop& main(); -protected: - EventLoop(); - private: + void waitForEvent(); + +#ifdef USE_SDL + void handleKeyEvent(Event::Type, const SDL_KeyboardEvent&); +#endif + struct QueuedEvent { Object* receiver { nullptr }; OwnPtr event; diff --git a/Widgets/EventLoopSDL.cpp b/Widgets/EventLoopSDL.cpp deleted file mode 100644 index 13a96c7562..0000000000 --- a/Widgets/EventLoopSDL.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "EventLoopSDL.h" -#include "Event.h" -#include -#include "Widget.h" -#include "WindowManager.h" -#include - -EventLoopSDL::EventLoopSDL() -{ -} - -EventLoopSDL::~EventLoopSDL() -{ -} - -static inline MouseButton toMouseButton(byte sdlButton) -{ - if (sdlButton == 1) - return MouseButton::Left; - if (sdlButton == 2) - return MouseButton::Middle; - if (sdlButton == 3) - return MouseButton::Right; - ASSERT_NOT_REACHED(); - return MouseButton::None; -} - -void EventLoopSDL::handleKeyEvent(Event::Type type, const SDL_KeyboardEvent& sdlKey) -{ - auto keyEvent = make(type, 0); - int key = 0; - - switch (sdlKey.keysym.sym) { - case SDLK_LEFT: key = KeyboardKey::LeftArrow; break; - case SDLK_RIGHT: key = KeyboardKey::RightArrow; break; - case SDLK_UP: key = KeyboardKey::UpArrow; break; - case SDLK_DOWN: key = KeyboardKey::DownArrow; break; - case SDLK_BACKSPACE: key = KeyboardKey::Backspace; break; - case SDLK_RETURN: key = KeyboardKey::Return; break; - } - keyEvent->m_key = key; - - if (sdlKey.keysym.sym > SDLK_UNKNOWN && sdlKey.keysym.sym <= 'z') { - char buf[] = { 0, 0 }; - char& ch = buf[0]; - ch = (char)sdlKey.keysym.sym; - if (sdlKey.keysym.mod & KMOD_SHIFT) { - if (ch >= 'a' && ch <= 'z') { - ch &= ~0x20; - } else { - switch (ch) { - case '1': ch = '!'; break; - case '2': ch = '@'; break; - case '3': ch = '#'; break; - case '4': ch = '$'; break; - case '5': ch = '%'; break; - case '6': ch = '^'; break; - case '7': ch = '&'; break; - case '8': ch = '*'; break; - case '9': ch = '('; break; - case '0': ch = ')'; break; - case '-': ch = '_'; break; - case '=': ch = '+'; break; - case '`': ch = '~'; break; - case ',': ch = '<'; break; - case '.': ch = '>'; break; - case '/': ch = '?'; break; - case '[': ch = '{'; break; - case ']': ch = '}'; break; - case '\\': ch = '|'; break; - case '\'': ch = '"'; break; - case ';': ch = ':'; break; - } - } - } - keyEvent->m_text = buf; - } - - keyEvent->m_shift = sdlKey.keysym.mod & KMOD_SHIFT; - keyEvent->m_ctrl = sdlKey.keysym.mod & KMOD_CTRL; - keyEvent->m_alt = sdlKey.keysym.mod & KMOD_ALT; - - postEvent(&WindowManager::the(), std::move(keyEvent)); -} - -void EventLoopSDL::waitForEvent() -{ - SDL_Event sdlEvent; - while (SDL_PollEvent(&sdlEvent) != 0) { - switch (sdlEvent.type) { - case SDL_QUIT: - postEvent(nullptr, make()); - return; - case SDL_WINDOWEVENT: - if (sdlEvent.window.event == SDL_WINDOWEVENT_EXPOSED) { - // Spam paint events whenever we get exposed. - // This is obviously not ideal, but the SDL backend here is just a prototype anyway. - postEvent(&WindowManager::the(), make()); - } - return; - case SDL_MOUSEMOTION: - postEvent(&WindowManager::the(), make(Event::MouseMove, sdlEvent.motion.x, sdlEvent.motion.y)); - return; - case SDL_MOUSEBUTTONDOWN: - postEvent(&WindowManager::the(), make(Event::MouseDown, sdlEvent.button.x, sdlEvent.button.y, toMouseButton(sdlEvent.button.button))); - return; - case SDL_MOUSEBUTTONUP: - postEvent(&WindowManager::the(), make(Event::MouseUp, sdlEvent.button.x, sdlEvent.button.y, toMouseButton(sdlEvent.button.button))); - return; - case SDL_KEYDOWN: - handleKeyEvent(Event::KeyDown, sdlEvent.key); - return; - case SDL_KEYUP: - handleKeyEvent(Event::KeyUp, sdlEvent.key); - return; - } - } -} - diff --git a/Widgets/EventLoopSDL.h b/Widgets/EventLoopSDL.h deleted file mode 100644 index 733400689f..0000000000 --- a/Widgets/EventLoopSDL.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "Event.h" -#include "EventLoop.h" -#include - -class EventLoopSDL final : public EventLoop { -public: - EventLoopSDL(); - virtual ~EventLoopSDL() override; - -private: - virtual void waitForEvent() override; - - void handleKeyEvent(Event::Type, const SDL_KeyboardEvent&); -}; - diff --git a/Widgets/Makefile b/Widgets/Makefile index 3be526f0b7..cf2c66b8f6 100644 --- a/Widgets/Makefile +++ b/Widgets/Makefile @@ -10,7 +10,6 @@ VFS_OBJS = \ AbstractScreen.o \ FrameBuffer.o \ EventLoop.o \ - EventLoopSDL.o \ Rect.o \ Object.o \ Widget.o \ diff --git a/Widgets/test.cpp b/Widgets/test.cpp index 01f77d2d48..2ba6192f90 100644 --- a/Widgets/test.cpp +++ b/Widgets/test.cpp @@ -1,5 +1,5 @@ #include "FrameBuffer.h" -#include "EventLoopSDL.h" +#include "EventLoop.h" #include "RootWidget.h" #include "Label.h" #include "Button.h" @@ -17,7 +17,7 @@ int main(int argc, char** argv) FrameBuffer fb(800, 600); fb.show(); - EventLoopSDL loop; + EventLoop loop; RootWidget w; WindowManager::the().setRootWidget(&w);