From 1ec25d036c210032fae2449b96865c810cb4e2dc Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 23 Apr 2021 16:29:26 +0200 Subject: [PATCH] Added cursor support --- examples/main.cpp | 2 +- include/SDLU.hpp | 1 + include/structures/Cursor.hpp | 38 +++++++++++++++++++++ include/structures/Window.hpp | 25 +++----------- src/structures/Cursor.cpp | 62 +++++++++++++++++++++++++++++++++++ src/structures/Window.cpp | 27 +++------------ 6 files changed, 110 insertions(+), 45 deletions(-) create mode 100644 include/structures/Cursor.hpp create mode 100644 src/structures/Cursor.cpp diff --git a/examples/main.cpp b/examples/main.cpp index 896b693..dd579da 100644 --- a/examples/main.cpp +++ b/examples/main.cpp @@ -27,7 +27,7 @@ int main(int argc, char** argv) window.SetTitle("New Title"); window.SetIcon(64, 64, icon_data); - // window.SetMouseCursor(SDL_SYSTEM_CURSOR_CROSSHAIR); + window.SetMouseCursor(sdlu::Cursor::Type::Crosshair); window.SetMaxFramerate(144); SDL_Event event; diff --git a/include/SDLU.hpp b/include/SDLU.hpp index cb049e6..bee07e3 100644 --- a/include/SDLU.hpp +++ b/include/SDLU.hpp @@ -2,6 +2,7 @@ #include #include +#include namespace sdlu { // TODO: Eventually we should initialize things once the object gets created diff --git a/include/structures/Cursor.hpp b/include/structures/Cursor.hpp new file mode 100644 index 0000000..bb55408 --- /dev/null +++ b/include/structures/Cursor.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "Vector2.hpp" +#include "Util.hpp" + +struct SDL_Cursor; +struct SDL_Surface; + +SDLU_BEGIN + +class Cursor +{ +public: + enum class Type { + Arrow, IBeam, Wait, Crosshair, WaitArrow, + SizeNWSE, SizeNESW, SizeWE, SizeNS, SizeAll, + No, Hand + }; + + friend class Window; + +public: + Cursor(); + Cursor(Type type); + Cursor(const Cursor& other) = delete; + Cursor(Cursor&& other) noexcept; + + ~Cursor(); + + bool LoadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hotspot); + bool LoadFromSurface(SDL_Surface* surface, Vector2u hotspot); + bool LoadFromSystem(Type type); + +private: + SDL_Cursor* cursor; +}; + +SDLU_END \ No newline at end of file diff --git a/include/structures/Window.hpp b/include/structures/Window.hpp index 9925cc3..76a13e1 100644 --- a/include/structures/Window.hpp +++ b/include/structures/Window.hpp @@ -17,6 +17,8 @@ struct SDL_Surface; struct SDL_Cursor; SDLU_BEGIN +class Cursor; + /** * @brief Stores information about a window. You probably want RenderWindow. */ @@ -230,28 +232,9 @@ public: /** * @brief Changes the mouse cursor * - * @param[in] surface A pointer to a SDL_Surface containing sprite data - * @param[in] clickspot The effective position of the cursor relative to the top left of the sprite + * @param[in] cursor The cursor object holding cursor data */ - void SetMouseCursor(SDL_Surface* surface, Vector2u clickspot); - - /** - * @brief Changes the mouse cursor - * - * @param[in] pixels An array of color data (RGBA as seperate 8-bit values) - * @param[in] size Size of the cursor - * @param[in] clickspot The effective position of the cursor relative to the top left of the sprite - */ - void SetMouseCursor(const Uint8* pixels, Vector2u size, Vector2u clickspot); - - /** - * @brief Changes the mouse cursor - * - * @param[in] pixels An array of color data (RGBA as one 32-bit value) - * @param[in] size Size of the cursor - * @param[in] clickspot The effective position of the cursor relative to the top left of the sprite - */ - void SetMouseCursor(const Uint32* pixels, Vector2u size, Vector2u clickspot); + void SetMouseCursor(const Cursor& cursor); protected: SDL_Window* window; diff --git a/src/structures/Cursor.cpp b/src/structures/Cursor.cpp new file mode 100644 index 0000000..c7bbfe0 --- /dev/null +++ b/src/structures/Cursor.cpp @@ -0,0 +1,62 @@ +#include "structures/Cursor.hpp" + +#include + +SDLU_BEGIN + +Cursor::Cursor() : + cursor(SDL_CreateSystemCursor(static_cast(Type::Arrow))) +{ + +} + +Cursor::Cursor(Type type) : + cursor(SDL_CreateSystemCursor(static_cast(type))) +{ +} + +Cursor::Cursor(Cursor&& other) noexcept +{ + this->cursor = other.cursor; + other.cursor = nullptr; +} + +Cursor::~Cursor() +{ + SDL_FreeCursor(cursor); +} + +bool Cursor::LoadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hotspot) +{ + SDL_FreeCursor(cursor); + cursor = SDL_CreateCursor(pixels, nullptr, size.x, size.y, hotspot.x, hotspot.y); + + if (IS_NULLPTR(cursor)) + return false; + + return true; +} + +bool Cursor::LoadFromSurface(SDL_Surface* surface, Vector2u hotspot) +{ + SDL_FreeCursor(cursor); + cursor = SDL_CreateColorCursor(surface, hotspot.x, hotspot.y); + + if (IS_NULLPTR(cursor)) + return false; + + return true; +} + +bool Cursor::LoadFromSystem(Type type) +{ + SDL_FreeCursor(cursor); + cursor = SDL_CreateSystemCursor(static_cast(type)); + + if (IS_NULLPTR(cursor)) + return false; + + return true; +} + +SDLU_END \ No newline at end of file diff --git a/src/structures/Window.cpp b/src/structures/Window.cpp index 6591d02..027a950 100644 --- a/src/structures/Window.cpp +++ b/src/structures/Window.cpp @@ -3,6 +3,8 @@ #include #include +#include "structures/Cursor.hpp" + SDLU_BEGIN Window::Window() : window(nullptr) @@ -204,30 +206,9 @@ void Window::SetMouseCursor(SDL_Cursor* cursor) SDL_SetCursor(cursor); } -void Window::SetMouseCursor(SDL_Surface* surface, Vector2u clickspot) +void Window::SetMouseCursor(const Cursor& cursor) { - SDL_Cursor* _cursor = SDL_CreateColorCursor(surface, clickspot.x, clickspot.y); - SDL_SetCursor(_cursor); -} - -void Window::SetMouseCursor(const Uint8* pixels, Vector2u size, Vector2u clickspot) -{ - size_t _size = static_cast(size.x) * static_cast(size.y) * 4; - void* _pixels = malloc(_size); - memcpy(_pixels, pixels, _size); - SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormatFrom(_pixels, - size.x, size.y, 32, 8 * size.x, SDL_PIXELFORMAT_RGBA8888); - this->SetMouseCursor(surface, clickspot); -} - -void Window::SetMouseCursor(const Uint32* pixels, Vector2u size, Vector2u clickspot) -{ - size_t _size = static_cast(size.x) * static_cast(size.y) * 4; - void* _pixels = malloc(_size); - memcpy(_pixels, pixels, _size); - SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormatFrom(_pixels, - size.x, size.y, 32, 8 * size.x, SDL_PIXELFORMAT_RGBA32); - this->SetMouseCursor(surface, clickspot); + SDL_SetCursor(cursor.cursor); } void Window::OnCreate()