diff options
| -rw-r--r-- | include/cru/platform/gui/sdl/UiApplication.h | 6 | ||||
| -rw-r--r-- | include/cru/platform/gui/sdl/Window.h | 1 | ||||
| -rw-r--r-- | src/platform/gui/sdl/UiApplication.cpp | 43 | ||||
| -rw-r--r-- | src/platform/gui/sdl/Window.cpp | 8 |
4 files changed, 57 insertions, 1 deletions
diff --git a/include/cru/platform/gui/sdl/UiApplication.h b/include/cru/platform/gui/sdl/UiApplication.h index be5ae102..776a4d80 100644 --- a/include/cru/platform/gui/sdl/UiApplication.h +++ b/include/cru/platform/gui/sdl/UiApplication.h @@ -6,6 +6,7 @@ #include <cru/base/Timer.h> #include <cru/platform/graphics/Factory.h> +#include <SDL3/SDL_events.h> #include <atomic> #include <chrono> #include <cstdint> @@ -18,7 +19,8 @@ class SdlUiApplication : public SdlResource, public virtual IUiApplication { friend SdlWindow; public: - explicit SdlUiApplication(graphics::IGraphicsFactory* graphics_factory, bool release_graphics_factory); + explicit SdlUiApplication(graphics::IGraphicsFactory* graphics_factory, + bool release_graphics_factory); ~SdlUiApplication(); public: @@ -61,6 +63,8 @@ class SdlUiApplication : public SdlResource, public virtual IUiApplication { long long SetTimer(std::chrono::milliseconds milliseconds, std::function<void()> action, bool repeat); + bool DispatchEvent(const SDL_Event& event); + private: graphics::IGraphicsFactory* graphics_factory_; bool release_graphics_factory_; diff --git a/include/cru/platform/gui/sdl/Window.h b/include/cru/platform/gui/sdl/Window.h index 9947a1b9..22b797b5 100644 --- a/include/cru/platform/gui/sdl/Window.h +++ b/include/cru/platform/gui/sdl/Window.h @@ -96,6 +96,7 @@ class SdlWindow : public SdlResource, public virtual INativeWindow { private: SdlUiApplication* application_; SDL_Window* sdl_window_; + SDL_WindowID sdl_window_id_; Rect client_rect_; SdlWindow* parent_; EventHandlerRevokerGuard parent_create_guard_; diff --git a/src/platform/gui/sdl/UiApplication.cpp b/src/platform/gui/sdl/UiApplication.cpp index c876ad19..d2275a37 100644 --- a/src/platform/gui/sdl/UiApplication.cpp +++ b/src/platform/gui/sdl/UiApplication.cpp @@ -11,6 +11,7 @@ #include <algorithm> #include <chrono> #include <functional> +#include <optional> namespace cru::platform::gui::sdl { SdlUiApplication::SdlUiApplication(graphics::IGraphicsFactory* graphics_factory, @@ -48,6 +49,8 @@ int SdlUiApplication::Run() { break; } + DispatchEvent(event); + delete_later_pool_.Clean(); } @@ -153,4 +156,44 @@ long long SdlUiApplication::SetTimer(std::chrono::milliseconds milliseconds, PostEmptyEvent(); return timers_.Add(std::move(action), milliseconds, repeat); } + +namespace { +std::optional<SDL_WindowID> GetEventWindowId(const SDL_Event& event) { + switch (event.type) { + case SDL_EVENT_WINDOW_MOVED: + case SDL_EVENT_WINDOW_RESIZED: + case SDL_EVENT_WINDOW_SHOWN: + case SDL_EVENT_WINDOW_HIDDEN: + case SDL_EVENT_WINDOW_MINIMIZED: + case SDL_EVENT_WINDOW_FOCUS_GAINED: + case SDL_EVENT_WINDOW_FOCUS_LOST: + case SDL_EVENT_WINDOW_MOUSE_ENTER: + case SDL_EVENT_WINDOW_MOUSE_LEAVE: + case SDL_EVENT_WINDOW_DESTROYED: + return event.window.windowID; + case SDL_EVENT_MOUSE_BUTTON_DOWN: + case SDL_EVENT_MOUSE_BUTTON_UP: + return event.button.windowID; + case SDL_EVENT_MOUSE_WHEEL: + return event.wheel.windowID; + case SDL_EVENT_KEY_DOWN: + case SDL_EVENT_KEY_UP: + return event.key.windowID; + default: + return std::nullopt; + } +} +} // namespace + +bool SdlUiApplication::DispatchEvent(const SDL_Event& event) { + if (auto window_id = GetEventWindowId(event)) { + for (auto window : windows_) { + if (window->sdl_window_id_ == *window_id && window->HandleEvent(&event)) { + return true; + } + } + } + return false; +} + } // namespace cru::platform::gui::sdl diff --git a/src/platform/gui/sdl/Window.cpp b/src/platform/gui/sdl/Window.cpp index b0fcded4..3ab8cf4d 100644 --- a/src/platform/gui/sdl/Window.cpp +++ b/src/platform/gui/sdl/Window.cpp @@ -18,6 +18,8 @@ namespace cru::platform::gui::sdl { SdlWindow::SdlWindow(SdlUiApplication* application) : application_(application), + sdl_window_(nullptr), + sdl_window_id_(0), client_rect_(100, 100, 400, 200), parent_(nullptr) { application->RegisterWindow(this); @@ -214,6 +216,11 @@ void SdlWindow::DoCreateWindow() { throw SdlException("Failed to create window."); } + sdl_window_id_ = SDL_GetWindowID(sdl_window_); + if (sdl_window_id_ == 0) { + throw SdlException("Failed to get ID of created window."); + } + CreateEvent_.Raise(nullptr); CheckSdlReturn( @@ -309,6 +316,7 @@ bool SdlWindow::HandleEvent(const SDL_Event* event) { VisibilityChangeEvent_.Raise(WindowVisibilityType::Hide); DestroyEvent_.Raise(nullptr); sdl_window_ = nullptr; + sdl_window_id_ = 0; return true; } case SDL_EVENT_MOUSE_BUTTON_DOWN: { |
