From 80315e839a014c499402b46bd5a7dd5cfa462c91 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Wed, 6 Apr 2022 17:24:09 +0300 Subject: [PATCH] Add SDL2 cursor capabilities --- libs/sdl2/include/psemek/sdl2/cursor.hpp | 26 +++++++ libs/sdl2/source/cursor.cpp | 91 ++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 libs/sdl2/include/psemek/sdl2/cursor.hpp create mode 100644 libs/sdl2/source/cursor.cpp diff --git a/libs/sdl2/include/psemek/sdl2/cursor.hpp b/libs/sdl2/include/psemek/sdl2/cursor.hpp new file mode 100644 index 00000000..1b0bf002 --- /dev/null +++ b/libs/sdl2/include/psemek/sdl2/cursor.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +namespace psemek::sdl2 +{ + + struct cursor; + + struct cursor_provider + { + virtual cursor const & arrow() const = 0; + virtual cursor const & beam() const = 0; + virtual cursor const & hand() const = 0; + + virtual ~cursor_provider() {} + }; + + std::unique_ptr system_cursor_provider(); + + std::unique_ptr set_cursor_provider(std::unique_ptr new_provider); + cursor_provider const * get_cursor_provider(); + + void set_cursor(cursor const & c); + +} diff --git a/libs/sdl2/source/cursor.cpp b/libs/sdl2/source/cursor.cpp new file mode 100644 index 00000000..77b9631d --- /dev/null +++ b/libs/sdl2/source/cursor.cpp @@ -0,0 +1,91 @@ +#include +#include + +#include + +#include + +namespace psemek::sdl2 +{ + + namespace + { + + struct cursor_deleter + { + void operator() (SDL_Cursor * c) const + { + SDL_FreeCursor(c); + } + }; + + using cursor_ptr = std::unique_ptr; + + } + + struct cursor + { + cursor_ptr cursor; + }; + + namespace + { + + SDL_Cursor * create_system_cursor(SDL_SystemCursor id) + { + auto cursor = SDL_CreateSystemCursor(id); + if (!cursor) + log::warning() << "Failed to create system cursor: " << SDL_GetError(); + return cursor; + } + + struct system_cursor_provider_impl + : cursor_provider + { + system_cursor_provider_impl() + { + arrow_.cursor.reset(create_system_cursor(SDL_SYSTEM_CURSOR_ARROW)); + beam_.cursor.reset(create_system_cursor(SDL_SYSTEM_CURSOR_IBEAM)); + hand_.cursor.reset(create_system_cursor(SDL_SYSTEM_CURSOR_HAND)); + } + + cursor const & arrow() const override { return arrow_; } + cursor const & beam() const override { return beam_; } + cursor const & hand() const override { return hand_; } + + private: + cursor arrow_; + cursor beam_; + cursor hand_; + }; + + } + + std::unique_ptr system_cursor_provider() + { + return std::make_unique(); + } + + static std::unique_ptr current_provider; + + std::unique_ptr set_cursor_provider(std::unique_ptr new_provider) + { + std::swap(current_provider, new_provider); + return new_provider; + } + + cursor_provider const * get_cursor_provider() + { + static system_cursor_provider_impl const fallback; + if (!current_provider) + return &fallback; + return current_provider.get(); + } + + void set_cursor(cursor const & c) + { + SDL_SetCursor(c.cursor.get()); + } + + +}