diff options
author | Yuqian Yang <crupest@crupest.life> | 2025-10-16 23:57:23 +0800 |
---|---|---|
committer | Yuqian Yang <crupest@crupest.life> | 2025-10-16 23:57:23 +0800 |
commit | 2a9118d137b411b3871073bb6ab18ba98c225d34 (patch) | |
tree | b5fbcf4d6ca1023efd1f3a9383ae8b242b9aadf6 /src | |
parent | 0b0a8a4087bd3843d4aa9140a9f302423ad5fde8 (diff) | |
download | cru-2a9118d137b411b3871073bb6ab18ba98c225d34.tar.gz cru-2a9118d137b411b3871073bb6ab18ba98c225d34.tar.bz2 cru-2a9118d137b411b3871073bb6ab18ba98c225d34.zip |
Bootstrap sdl.
Diffstat (limited to 'src')
-rw-r--r-- | src/platform/gui/sdl/CMakeLists.txt | 8 | ||||
-rw-r--r-- | src/platform/gui/sdl/UiApplication.cpp | 102 | ||||
-rw-r--r-- | src/platform/gui/sdl/Window.cpp | 170 |
3 files changed, 280 insertions, 0 deletions
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 <algorithm> + +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<void()> 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<void()> action) { + return event_loop_.SetImmediate(std::move(action)); +} + +long long SdlUiApplication::SetTimeout(std::chrono::milliseconds milliseconds, + std::function<void()> action) { + return event_loop_.SetTimeout(std::move(action), std::move(milliseconds)); +} + +long long SdlUiApplication::SetInterval(std::chrono::milliseconds milliseconds, + std::function<void()> action) { + return event_loop_.SetInterval(std::move(action), std::move(milliseconds)); +} + +void SdlUiApplication::CancelTimer(long long id) { + return event_loop_.CancelTimer(static_cast<int>(id)); +} + +std::vector<INativeWindow *> SdlUiApplication::GetAllWindow() { + std::vector<INativeWindow *> 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 <SDL_video.h> +#include <cairo-xcb.h> +#include <cairo.h> +#include <cassert> +#include <memory> +#include <optional> + +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<SdlWindow>(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<ICursor> cursor) { + if (!sdl_window_) return; + NotImplemented(); +} + +void SdlWindow::SetToForeground() { + SetVisibility(WindowVisibilityType::Show); + NotImplemented(); +} + +void SdlWindow::RequestRepaint() { + if (!sdl_window_) return; + NotImplemented(); +} + +std::unique_ptr<graphics::IPainter> SdlWindow::BeginPaint() { + if (!sdl_window_.has_value()) { + return std::make_unique<graphics::NullPainter>(); + } + + NotImplemented(); +} + +IEvent<std::nullptr_t> *SdlWindow::CreateEvent() { return &create_event_; } + +IEvent<std::nullptr_t> *SdlWindow::DestroyEvent() { return &destroy_event_; } + +IEvent<std::nullptr_t> *SdlWindow::PaintEvent() { return &paint_event_; } + +IEvent<WindowVisibilityType> *SdlWindow::VisibilityChangeEvent() { + return &visibility_change_event_; +} + +IEvent<Size> *SdlWindow::ResizeEvent() { return &resize_event_; } + +IEvent<FocusChangeType> *SdlWindow::FocusEvent() { return &focus_event_; } + +IEvent<MouseEnterLeaveType> *SdlWindow::MouseEnterLeaveEvent() { + return &mouse_enter_leave_event_; +} + +IEvent<Point> *SdlWindow::MouseMoveEvent() { return &mouse_move_event_; } + +IEvent<NativeMouseButtonEventArgs> *SdlWindow::MouseDownEvent() { + return &mouse_down_event_; +} + +IEvent<NativeMouseButtonEventArgs> *SdlWindow::MouseUpEvent() { + return &mouse_up_event_; +} + +IEvent<NativeMouseWheelEventArgs> *SdlWindow::MouseWheelEvent() { + return &mouse_wheel_event_; +} + +IEvent<NativeKeyEventArgs> *SdlWindow::KeyDownEvent() { + return &key_down_event_; +} + +IEvent<NativeKeyEventArgs> *SdlWindow::KeyUpEvent() { return &key_up_event_; } + +IInputMethodContext *SdlWindow::GetInputMethodContext() { NotImplemented(); } + +std::optional<SDL_Window *> SdlWindow::GetSdlWindow() { return sdl_window_; } + +SdlUiApplication *SdlWindow::GetSdlUiApplication() { return application_; } + +} // namespace cru::platform::gui::sdl |