Implement cursor support

This commit is contained in:
Dmitry Marakasov 2015-01-06 17:13:42 +03:00
parent a657e9e52b
commit eb7c8627e8
5 changed files with 324 additions and 0 deletions

View File

@ -100,6 +100,7 @@ SET(LIBRARY_SOURCES
SDL2pp/AudioDevice.cc SDL2pp/AudioDevice.cc
SDL2pp/AudioLock.cc SDL2pp/AudioLock.cc
SDL2pp/AudioSpec.cc SDL2pp/AudioSpec.cc
SDL2pp/Cursor.cc
SDL2pp/Exception.cc SDL2pp/Exception.cc
SDL2pp/Point.cc SDL2pp/Point.cc
SDL2pp/RWops.cc SDL2pp/RWops.cc
@ -118,6 +119,7 @@ SET(LIBRARY_HEADERS
SDL2pp/AudioDevice.hh SDL2pp/AudioDevice.hh
SDL2pp/AudioSpec.hh SDL2pp/AudioSpec.hh
SDL2pp/ContainerRWops.hh SDL2pp/ContainerRWops.hh
SDL2pp/Cursor.hh
SDL2pp/Exception.hh SDL2pp/Exception.hh
SDL2pp/Optional.hh SDL2pp/Optional.hh
SDL2pp/Point.hh SDL2pp/Point.hh

79
SDL2pp/Cursor.cc Normal file
View File

@ -0,0 +1,79 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <SDL2pp/Cursor.hh>
#include <SDL2pp/Surface.hh>
#include <SDL2pp/Exception.hh>
namespace SDL2pp {
Cursor::Cursor(SDL_Cursor* cursor) : cursor_(cursor) {
}
Cursor Cursor::CreateSystemCursor(SDL_SystemCursor id) {
SDL_Cursor* cursor = SDL_CreateSystemCursor(id);
if (cursor == nullptr)
throw Exception("SDL_CreateSystemCursor failed");
return Cursor(cursor);
}
Cursor Cursor::CreateCursor(const Uint8* data, const Uint8* mask, int w, int h, int hot_x, int hot_y) {
SDL_Cursor* cursor = SDL_CreateCursor(data, mask, w, h, hot_x, hot_y);
if (cursor == nullptr)
throw Exception("SDL_CreateCursor failed");
return Cursor(cursor);
}
Cursor Cursor::CreateColorCursor(const Surface& surface, int hot_x, int hot_y) {
SDL_Cursor* cursor = SDL_CreateColorCursor(surface.Get(), hot_x, hot_y);
if (cursor == nullptr)
throw Exception("SDL_CreateColorCursor failed");
return Cursor(cursor);
}
Cursor::~Cursor() {
if (cursor_ != nullptr)
SDL_FreeCursor(cursor_);
}
Cursor::Cursor(Cursor&& other) noexcept : cursor_(other.cursor_) {
other.cursor_ = nullptr;
}
Cursor& Cursor::operator=(Cursor&& other) noexcept {
if (&other == this)
return *this;
if (cursor_ != nullptr)
SDL_FreeCursor(cursor_);
cursor_ = other.cursor_;
other.cursor_ = nullptr;
return *this;
}
SDL_Cursor* Cursor::Get() const {
return cursor_;
}
void Cursor::Set() {
SDL_SetCursor(cursor_);
}
}

144
SDL2pp/Cursor.hh Normal file
View File

@ -0,0 +1,144 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL2PP_CURSOR_HH
#define SDL2PP_CURSOR_HH
#include <SDL2/SDL_mouse.h>
namespace SDL2pp {
class Surface;
////////////////////////////////////////////////////////////
/// \brief Mouse pointer image
///
/// \ingroup windows
///
/// \headerfile SDL2pp/Cursor.hh
///
////////////////////////////////////////////////////////////
class Cursor {
private:
SDL_Cursor* cursor_; ///< Contained SDL_Cursor structure
public:
////////////////////////////////////////////////////////////
/// \brief Construct from existing SDL_Cursor structure
///
/// \param texture Existing SDL_Cursor to manage
///
////////////////////////////////////////////////////////////
Cursor(SDL_Cursor* cursor);
////////////////////////////////////////////////////////////
/// \brief Create system cursor
///
/// \param id System cursor enum value
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_CreateSystemCursor
///
////////////////////////////////////////////////////////////
static Cursor CreateSystemCursor(SDL_SystemCursor id);
////////////////////////////////////////////////////////////
/// \brief Create a cursor using the specified bitmap data and mask (in MSB format)
///
/// \param data Color value for each pixel of the cursor
/// \param mask Mask value for each pixel of the cursor
/// \param w Width of the cursor
/// \param h Height of the cursor
/// \param hot_x X-axis location of the upper left corner of the cursor relative to the actual mouse position
/// \param hot_x Y-axis location of the upper left corner of the cursor relative to the actual mouse position
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_CreateCursor
///
////////////////////////////////////////////////////////////
static Cursor CreateCursor(const Uint8* data, const Uint8* mask, int w, int h, int hot_x, int hot_y);
////////////////////////////////////////////////////////////
/// \brief Create a cursor using the specified bitmap data and mask (in MSB format)
///
/// \param surface SDL2pp::Surface representing the cursor image
/// \param hot_x X position of the cursor hot spot
/// \param hot_y Y position of the cursor hot spot
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_CreateColorCursor
///
////////////////////////////////////////////////////////////
static Cursor CreateColorCursor(const Surface& surface, int hot_x, int hot_y);
////////////////////////////////////////////////////////////
/// \brief Destructor
///
/// \see http://wiki.libsdl.org/SDL_FreeCursor
///
////////////////////////////////////////////////////////////
virtual ~Cursor();
////////////////////////////////////////////////////////////
/// \brief Move constructor
///
/// \param other SDL2pp::Cursor object to move data from
///
////////////////////////////////////////////////////////////
Cursor(Cursor&& other) noexcept;
////////////////////////////////////////////////////////////
/// \brief Move assignment
///
/// \param other SDL2pp::Cursor object to move data from
///
/// \returns Reference to self
///
////////////////////////////////////////////////////////////
Cursor& operator=(Cursor&& other) noexcept;
// Deleted copy constructor and assignment
Cursor(const Cursor& other) = delete;
Cursor& operator=(const Cursor& other) = delete;
////////////////////////////////////////////////////////////
/// \brief Get pointer to contained SDL_Cursor structure
///
/// \returns Pointer to contained SDL_Cursor structure
///
////////////////////////////////////////////////////////////
SDL_Cursor* Get() const;
////////////////////////////////////////////////////////////
/// \brief Set the active cursor
///
/// \see http://wiki.libsdl.org/SDL_SetCursor
///
////////////////////////////////////////////////////////////
void Set();
};
}
#endif

View File

@ -15,6 +15,9 @@ TARGET_LINK_LIBRARIES(audio_sine SDL2pp)
ADD_EXECUTABLE(audio_wav audio_wav.cc) ADD_EXECUTABLE(audio_wav audio_wav.cc)
TARGET_LINK_LIBRARIES(audio_wav SDL2pp) TARGET_LINK_LIBRARIES(audio_wav SDL2pp)
ADD_EXECUTABLE(cursor cursor.cc)
TARGET_LINK_LIBRARIES(cursor SDL2pp)
IF(SDL2PP_WITH_IMAGE) IF(SDL2PP_WITH_IMAGE)
ADD_EXECUTABLE(image image.cc) ADD_EXECUTABLE(image image.cc)
TARGET_LINK_LIBRARIES(image SDL2pp) TARGET_LINK_LIBRARIES(image SDL2pp)

96
examples/cursor.cc Normal file
View File

@ -0,0 +1,96 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2pp/SDL.hh>
#include <SDL2pp/Window.hh>
#include <SDL2pp/Renderer.hh>
#include <SDL2pp/Exception.hh>
#include <SDL2pp/Cursor.hh>
#include <SDL2pp/Surface.hh>
#include <SDL2pp/Optional.hh>
using namespace SDL2pp;
Uint8 cursor_data[8] = { 0x38, 0x28, 0xEE, 0x82, 0xEE, 0x28, 0x38, 0x00 };
Uint8 cursor_mask[8] = { 0x38, 0x38, 0xFE, 0xFE, 0xFE, 0x38, 0x38, 0x00 };
Cursor GenCursor(int mode) {
switch (mode % 4) {
default:
return Cursor::CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
case 1:
return Cursor::CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
case 2:
return Cursor::CreateCursor(cursor_data, cursor_mask, 8, 8, 3, 3);
case 3:
{
Surface surf(TESTDATA_DIR "/test.png");
return Cursor::CreateColorCursor(surf, surf.GetWidth() / 2, surf.GetHeight() / 2);
}
}
}
int Run() {
SDL sdl(SDL_INIT_VIDEO);
Window window("libSDL2pp demo: cursors", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_RESIZABLE);
Renderer render(window, -1, SDL_RENDERER_ACCELERATED);
int cursormode = 0;
Optional<Cursor> cur;
while (1) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && (event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_q))) {
return 0;
} else if (event.type == SDL_MOUSEBUTTONDOWN) {
cur = GenCursor(++cursormode);
cur->Set();
}
}
// Clear screen
render.SetDrawColor(0, 32, 32);
render.Clear();
render.Present();
SDL_Delay(1);
}
return 0;
}
int main() {
try {
return Run();
} catch (Exception& e) {
std::cerr << "Error: " << e.what() << " (" << e.GetSDLError() << ")" << std::endl;
} catch (std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return -1;
}