From 2a9118d137b411b3871073bb6ab18ba98c225d34 Mon Sep 17 00:00:00 2001 From: Yuqian Yang Date: Thu, 16 Oct 2025 23:57:23 +0800 Subject: Bootstrap sdl. --- src/platform/gui/sdl/CMakeLists.txt | 8 ++ src/platform/gui/sdl/UiApplication.cpp | 102 ++++++++++++++++++++ src/platform/gui/sdl/Window.cpp | 170 +++++++++++++++++++++++++++++++++ 3 files changed, 280 insertions(+) create mode 100644 src/platform/gui/sdl/UiApplication.cpp create mode 100644 src/platform/gui/sdl/Window.cpp (limited to 'src') diff --git a/src/platform/gui/sdl/CMakeLists.txt b/src/platform/gui/sdl/CMakeLists.txt index 5dcc408b..f4266622 100644 --- a/src/platform/gui/sdl/CMakeLists.txt +++ b/src/platform/gui/sdl/CMakeLists.txt @@ -1,2 +1,10 @@ find_package(SDL2 REQUIRED CONFIG REQUIRED COMPONENTS SDL2) +add_library(CruPlatformGuiSdl + UiApplication.cpp + Window.cpp +) +target_link_libraries(CruPlatformGuiSdl PUBLIC + CruPlatformGui CruPlatformGraphicsCairo + SDL2::SDL2 +) diff --git a/src/platform/gui/sdl/UiApplication.cpp b/src/platform/gui/sdl/UiApplication.cpp new file mode 100644 index 00000000..a961ce84 --- /dev/null +++ b/src/platform/gui/sdl/UiApplication.cpp @@ -0,0 +1,102 @@ + +#include "cru/platform/gui/sdl/UiApplication.h" + +#include "cru/base/Base.h" +#include "cru/platform/graphics/cairo/CairoGraphicsFactory.h" +#include "cru/platform/gui/sdl/Window.h" + +#include + +namespace cru::platform::gui::sdl { +SdlUiApplication::SdlUiApplication( + graphics::cairo::CairoGraphicsFactory *cairo_factory) { + release_cairo_factory_ = false; + if (cairo_factory == nullptr) { + cairo_factory = new graphics::cairo::CairoGraphicsFactory(); + release_cairo_factory_ = true; + } + cairo_factory_ = cairo_factory; +} + +SdlUiApplication::~SdlUiApplication() { + if (release_cairo_factory_) { + delete cairo_factory_; + } +} + +graphics::cairo::CairoGraphicsFactory *SdlUiApplication::GetCairoFactory() { + return cairo_factory_; +} + +int SdlUiApplication::Run() { + auto exit_code = event_loop_.Run(); + + for (const auto &handler : this->quit_handlers_) { + handler(); + } + + return exit_code; +} + +void SdlUiApplication::RequestQuit(int quit_code) { + event_loop_.RequestQuit(quit_code); +} + +void SdlUiApplication::AddOnQuitHandler(std::function handler) { + this->quit_handlers_.push_back(std::move(handler)); +} + +bool SdlUiApplication::IsQuitOnAllWindowClosed() { + return is_quit_on_all_window_closed_; +} + +void SdlUiApplication::SetQuitOnAllWindowClosed( + bool quit_on_all_window_closed) { + is_quit_on_all_window_closed_ = quit_on_all_window_closed; +} + +long long SdlUiApplication::SetImmediate(std::function action) { + return event_loop_.SetImmediate(std::move(action)); +} + +long long SdlUiApplication::SetTimeout(std::chrono::milliseconds milliseconds, + std::function action) { + return event_loop_.SetTimeout(std::move(action), std::move(milliseconds)); +} + +long long SdlUiApplication::SetInterval(std::chrono::milliseconds milliseconds, + std::function action) { + return event_loop_.SetInterval(std::move(action), std::move(milliseconds)); +} + +void SdlUiApplication::CancelTimer(long long id) { + return event_loop_.CancelTimer(static_cast(id)); +} + +std::vector SdlUiApplication::GetAllWindow() { + std::vector windows(windows_.size()); + std::ranges::copy(windows_, windows.begin()); + return windows; +} + +INativeWindow *SdlUiApplication::CreateWindow() { return new SdlWindow(this); } + +cru::platform::graphics::IGraphicsFactory * +SdlUiApplication::GetGraphicsFactory() { + return cairo_factory_; +} + +ICursorManager *SdlUiApplication::GetCursorManager() { NotImplemented(); } + +IClipboard *SdlUiApplication::GetClipboard() { NotImplemented(); } + +IMenu *SdlUiApplication::GetApplicationMenu() { return nullptr; } + +void SdlUiApplication::RegisterWindow(SdlWindow *window) { + windows_.push_back(window); +} + +void SdlUiApplication::UnregisterWindow(SdlWindow *window) { + std::erase(windows_, window); +} +} // namespace cru::platform::gui::sdl diff --git a/src/platform/gui/sdl/Window.cpp b/src/platform/gui/sdl/Window.cpp new file mode 100644 index 00000000..e802b82f --- /dev/null +++ b/src/platform/gui/sdl/Window.cpp @@ -0,0 +1,170 @@ +#include "cru/platform/gui/sdl/Window.h" +#include "cru/base/Base.h" +#include "cru/platform/Check.h" +#include "cru/platform/GraphicsBase.h" +#include "cru/platform/graphics/NullPainter.h" +#include "cru/platform/graphics/Painter.h" +#include "cru/platform/gui/Base.h" +#include "cru/platform/gui/Window.h" +#include "cru/platform/gui/sdl/UiApplication.h" + +#include +#include +#include +#include +#include +#include + +namespace cru::platform::gui::sdl { + +SdlWindow::SdlWindow(SdlUiApplication *application) + : application_(application), parent_(nullptr) { + application->RegisterWindow(this); +} + +SdlWindow::~SdlWindow() { application_->UnregisterWindow(this); } + +bool SdlWindow::IsCreated() { return sdl_window_.has_value(); } + +void SdlWindow::Close() { + if (sdl_window_) { + SDL_DestroyWindow(*sdl_window_); + } +} + +INativeWindow *SdlWindow::GetParent() { return parent_; } + +void SdlWindow::SetParent(INativeWindow *parent) { + parent_ = CheckPlatform(parent, GetPlatformIdUtf8()); + NotImplemented(); +} + +WindowStyleFlag SdlWindow::GetStyleFlag() { return style_; } + +void SdlWindow::SetStyleFlag(WindowStyleFlag flag) { + style_ = flag; + NotImplemented(); +} + +String SdlWindow::GetTitle() { NotImplemented(); } + +void SdlWindow::SetTitle(String title) { NotImplemented(); } + +WindowVisibilityType SdlWindow::GetVisibility() { NotImplemented(); } + +void SdlWindow::SetVisibility(WindowVisibilityType visibility) { + NotImplemented(); +} + +Size SdlWindow::GetClientSize() { return GetClientRect().GetSize(); } + +void SdlWindow::SetClientSize(const Size &size) { + auto rect = GetClientRect(); + SetClientRect(Rect(rect.GetLeftTop(), size)); +} + +Rect SdlWindow::GetClientRect() { + if (!sdl_window_) return {}; + NotImplemented(); +} + +void SdlWindow::SetClientRect(const Rect &rect) { + if (!sdl_window_) return; + NotImplemented(); +} + +Rect SdlWindow::GetWindowRect() { + if (!sdl_window_) return {}; + NotImplemented(); +} + +void SdlWindow::SetWindowRect(const Rect &rect) { + if (!sdl_window_) return; + NotImplemented(); +} + +bool SdlWindow::RequestFocus() { + if (!sdl_window_) return false; + NotImplemented(); +} + +Point SdlWindow::GetMousePosition() { NotImplemented(); } + +bool SdlWindow::CaptureMouse() { + if (!sdl_window_) return false; + NotImplemented(); +} + +bool SdlWindow::ReleaseMouse() { + if (!sdl_window_) return false; + NotImplemented(); +} + +void SdlWindow::SetCursor(std::shared_ptr cursor) { + if (!sdl_window_) return; + NotImplemented(); +} + +void SdlWindow::SetToForeground() { + SetVisibility(WindowVisibilityType::Show); + NotImplemented(); +} + +void SdlWindow::RequestRepaint() { + if (!sdl_window_) return; + NotImplemented(); +} + +std::unique_ptr SdlWindow::BeginPaint() { + if (!sdl_window_.has_value()) { + return std::make_unique(); + } + + NotImplemented(); +} + +IEvent *SdlWindow::CreateEvent() { return &create_event_; } + +IEvent *SdlWindow::DestroyEvent() { return &destroy_event_; } + +IEvent *SdlWindow::PaintEvent() { return &paint_event_; } + +IEvent *SdlWindow::VisibilityChangeEvent() { + return &visibility_change_event_; +} + +IEvent *SdlWindow::ResizeEvent() { return &resize_event_; } + +IEvent *SdlWindow::FocusEvent() { return &focus_event_; } + +IEvent *SdlWindow::MouseEnterLeaveEvent() { + return &mouse_enter_leave_event_; +} + +IEvent *SdlWindow::MouseMoveEvent() { return &mouse_move_event_; } + +IEvent *SdlWindow::MouseDownEvent() { + return &mouse_down_event_; +} + +IEvent *SdlWindow::MouseUpEvent() { + return &mouse_up_event_; +} + +IEvent *SdlWindow::MouseWheelEvent() { + return &mouse_wheel_event_; +} + +IEvent *SdlWindow::KeyDownEvent() { + return &key_down_event_; +} + +IEvent *SdlWindow::KeyUpEvent() { return &key_up_event_; } + +IInputMethodContext *SdlWindow::GetInputMethodContext() { NotImplemented(); } + +std::optional SdlWindow::GetSdlWindow() { return sdl_window_; } + +SdlUiApplication *SdlWindow::GetSdlUiApplication() { return application_; } + +} // namespace cru::platform::gui::sdl -- cgit v1.2.3